PDA

View Full Version : Fontmaps



Inagawa
09-19-2012, 01:11 PM
Hi there,

I wanted to share a (glimpse at a) cool thing that I made and ask how I could improve it. I am really giddy about the fact that it worked out nicely, so excuse the gloating that's inevitably present in the description below ;)

It's a fontmap generator. It can take any font, either installed or from a custom file and draw a condensed (bin packed) fontmap of symbols in any size and style using GDI+.
You then request a character and it returns its position, size and the index of the texture it's currently contained in.
It's also fully dynamic, so if you request a character that hasn't been before generated (and you allow the fontmap to be dynamic), the fontmap will automatically generate the character, add it to the texture and return the symbol.
The image below took +/- 13 seconds (it's 13000+ symbols in all styles possible and a lot of sizes). It's a 2048x2048

Screenshot (http://imageshack.us/a/img19/8871/screenshotani.png)

The text below has been written with the symbols that were dynamically generated, added to the fontmap and then extracted to be applied on quads. I love it.

http://imageshack.us/a/img685/6512/fontst.png

But enough with the gloating, I dearly need some advice. Do the fonts look okay when you see them? Could you look at a text like this for a long time? I have been continually staring at these fonts for so long that I honestly can't tell. Sometimes the font looks too blurry (GDI+ is set to AntiAliasGridFit), but japanese and arabic symbols look too pixelated. Using AntiAlias (No grid fit) fixes the second problem, but sometimes augments the blurriness on thin lines, makes them gray instead of black.

And second, (I know this is an OpenGL forum, but whom better to ask than you people, many of whom attempted the same thing, I'm sure) where could I find any information that could help me with creating my own GUI? Namely textboxes - none of my pitiful attempts at creating a textbox control succeeded. I need some design, structure or anything that would explain how exactly does a textbox (like the one I'm using right now) effectively manage its text.

Thank you for any help

carsten neumann
09-19-2012, 03:39 PM
One idea to improve the quality: render a character at a much larger size, calculate a distance map from it, and store that in your fontmap texture, see Alpha Tested Magnification.pdf (http://www.valvesoftware.com/publications/2007/SIGGRAPH2007_AlphaTestedMagnification.pdf) for details.

Inagawa
09-20-2012, 06:03 AM
Thanks for the suggestion, but this seems like more work than it would be worth. At least for now, when it's more important to get a basic UI going.

michagl
09-23-2012, 07:26 PM
I used to do quad fonts with OpenGL. But I have been basically working with Direct3D (no more than 9) for a long time since, but intend to get back into desktop OpenGL soon because it will be possible to move away from Direct3D (breaking away from legacy inertia) and because Direct3D is a dead end on Windows XP but OpenGL is not.

If you are using GDI+ then we are talking about Windows. I do not know about post D3D9 but there is D3DXCreateFont which I have tended to favor; especially because I needed to emulate the earlier Win32 Font APIs but in general if Unicode and i18n is a must D3DXCreateFont really does a lot for free. And it seem like it probably works similarly to what you (Inagawa) are doing here. Except obviously it's not OpenGL!

I don't know how it stacks up against the kind of font rendering we expect in a web browser. But it you need quite large or single pixel fonts it looks good.

But now what I am wondering is what on earth I will do if I am using OpenGL instead of Direct3D9. I know D3DX has a lot of "OpenGL" mode features. But I am just assuming the two are not compatible due to namesakes if nothing else. I would actually need to be able to emulate the Win32 APIs on Windows at least so this kind of approach will probably be a must.

Anyway at OP. If nothing else you might consider firing up Direct3D instead of GDI. As GDI is deprecated anyway. And drawing to a device context. And then copying that to OpenGL somehow. The main OpenGL context handle on Windows is a device context, so it would probably be compatible. But it would be nice to break away from micromanaging the placement too. I am wondering if GLUT has a way? I see wglUseFontOutlines.

Inagawa
09-24-2012, 10:11 AM
I am using GDI+, not GDI. And if I'm not mistaken, DirectWrite is the only thing superseding GDI+, no? I may be wrong, though. I really needed some robust way of rendering text as soon as possible so I can finally move on and get to programming the rest of the GUI, so GDI+ seemed like the obvious choice after picking apart the source code of other GUIs.

So to be honest, at this point I am far more interested in how to program an editable text box. For the life of me I can't figure it out. I don't have the luxury of thinking about the text as a string (and just render the text line by line with GDI+ like others do), but as a collection of quads and that complicates things beyond my capabilities. If anyone could please enlighten me even by a little, I'd be grateful, but as far as the matter with the fontmap goes, I can't change anything now.

Edit: Where are my manners, thank you for the advice, don't think I don't value it; it's just that by now my priorities are shifted away from the actual fontmap.

Alfonse Reinheart
09-24-2012, 10:50 AM
I don't have the luxury of thinking about the text as a string (and just render the text line by line with GDI+ like others do), but as a collection of quads and that complicates things beyond my capabilities.

That... is why you fail.

You're trying to think about a text box at the level of quad drawing. That's the wrong way to go; you should be thinking of text boxes at the level of the string, which you then use to generate the list of quads to draw.

Your edit box has two levels of functionality: modify a string based on user-input, and draw that string. If you try to do both of these at the same time, you won't get anywhere.

dukey
09-24-2012, 12:36 PM
I don't know too much about font stuff. But the default font in visual studio 2010 is so blurry, it's enough to give you eye cancer.

Inagawa
09-25-2012, 12:10 AM
That... is why you fail.

You're trying to think about a text box at the level of quad drawing. That's the wrong way to go; you should be thinking of text boxes at the level of the string, which you then use to generate the list of quads to draw.

Your edit box has two levels of functionality: modify a string based on user-input, and draw that string. If you try to do both of these at the same time, you won't get anywhere.

I agree, I came to much the same conclusion. But I was concerned about the performance, since I will have to - as you said - generate the quads. Anyway, I will try that and get back to you on this.

michagl
09-25-2012, 07:16 PM
I am pretty sure GDI+ is deprecated too. It's a mess of an API.

I would like to know myself how this is commonly done. I am thinking when it comes to the rendering you would want to be writing the quads to a dynamic vertex buffer, but I am not sure. Honestly I am surprised if there is not a (commonly used) higher level way to do truetype Unicode with OpenGL.

Alfonse Reinheart
09-25-2012, 07:32 PM
Honestly I am surprised if there is not a (commonly used) higher level way to do truetype Unicode with OpenGL.

Why would you be surprised by that? Do you know how hard full-fledged Unicode text layout is? I know of exactly two open-source libraries that can do Unicode text layout: ICU and Pango. Both of these libraries are designed to care as little as possible about how you actually render the glyphs.

Drawing some glyphs with OpenGL is easy. Drawing the right glyphs in the right place with any graphics API is the tricky part.

michagl
09-25-2012, 07:48 PM
Why would you be surprised by that? Do you know how hard full-fledged Unicode text layout is? I know of exactly two open-source libraries that can do Unicode text layout: ICU and Pango. Both of these libraries are designed to care as little as possible about how you actually render the glyphs.

Drawing some glyphs with OpenGL is easy. Drawing the right glyphs in the right place with any graphics API is the tricky part.

Well I will accept that as an answer. It's not something I've looked into, but for the record this is built into Windows. Look into DrawText. The easiest thing to do might be to render the text with Direct3D to either an overlay window or to a neutral device context with a dynamic texture if your text is the usual sort of thing you find in a video game.

That reminds me though that you can also use DrawText (or a related API; as I recall) in a way that does not actually display text, and then query the text that it would have drawn, so that effectively you end up with the Unicode layouts that you would find in the likes of Internet Explorer. You would just need to capture and render the glyphs somehow.

EDITED: I think that might be what you are supposed to do with wglUseFontOutlines and wglUseFontBitmaps (depending on the kind of font you have etc) but these are documented to rely on display lists, and I don't know how good those are anymore. I think the concept should be added to WebGL (due to the runtime limitations of JavaScript) but otherwise that is probably not the right way. It might be a good step for generating a font texture by whatever terms OpenGL uses for render target textures :)

EDITED: It's too bad those APIs do not expose the texture that the display lists would have used because that might save you the trouble of drawing the display lists to a render target.

michagl
09-25-2012, 07:57 PM
Why would you be surprised by that? Do you know how hard full-fledged Unicode text layout is? I know of exactly two open-source libraries that can do Unicode text layout: ICU and Pango.

Maybe instead of OpenVG Khronos should be pushing OpenUnicode or something first.

Alfonse Reinheart
09-25-2012, 08:07 PM
That wouldn't be an open-source library. That would be a specification that someone has to implement. Just like virtually everything else Khronos does. There's no point in providing a specification for a library like that.

michagl
09-25-2012, 08:56 PM
That wouldn't be an open-source library. That would be a specification that someone has to implement. Just like virtually everything else Khronos does. There's no point in providing a specification for a library like that.

While I was jesting. I dunno. Pango seems top heavy and doesn't feel like an open standard. ICU (thanks for the heads up) looks like something that should be under the hood so to speak. Fonts are central to graphics, and doing fonts without Unicode is almost pointless to go back to. At the same time Unicode is a lot to deal with. So having something potentially as widespread as OpenGL for Unicode would be pretty important. I think it would probably make more sense for something like GLUT or GLUT itself to implement. Windows has DrawText, so it really has a leg up on everyone else if something as simple to just use cannot be figured out by everyone else.

I mean if there is already wglUseFontOutlines which presumably can do any kind of font for Windows. Why not just modernize it. X has glXUseXFont apparently. These can render any font. They just need a portable layout framework to match them now that we are in the Unicode age.

PS: Literally DrawText is just like pick a font, any font, and give us a string to draw. It's that simple. You just have to deal with cobbling together your own hybrid fonts to make sure the glyphs you need are in the fonts you are drawing.

Alfonse Reinheart
09-25-2012, 09:22 PM
Why not just modernize it.

"Modernize it" into what? Into GLUT? Well, GLUT is defunct, so that would have to be FreeGLUT. And while it is active, I'm pretty sure they're not going to build a full Unicode text layout system into their application.

You want a lot of things, but they're not going to happen. Or more to the point, if you want them to happen, you are going to have to make them happen. If you want this in FreeGLUT, then put it into FreeGLUT; it's open source.

michagl
09-25-2012, 09:37 PM
Yeah that is the expectation. Meanwhile apparently non-Windows platforms do not have reasonable text rendering options for people like the OP. Not knowing what Apple has for their Macs.

That mentality just leads to confusion and imperialistic programming patterns which is not good for anyone.

Fortunately the OP seems to be working exclusively with Windows. So he/she has many options laid out before them here now.

If they were looking to be cross platform then they (apparently) have nothing.


PS: Everywhere I see OpenGL I see GLUT. So apparently it's still popular. I am working from the assumption that GLUT is basically the D3DX of OpenGL, but I am pretty willfully ignorant about these things. If not GLUT then it should be built directly into the OS (environment/window manager) side of things. If the OS doesn't have said features then it's already behind the ball. Disclaimer: I am not familiar with the status of Unicode fonts with X/Linux or OSX but X has font facilities so it should be able to do its own layouts without every application having a dependency on something like Pango and there is no reason why OpenGL could not or should not facilitate that.

michagl
09-25-2012, 09:50 PM
"Modernize it" into what? Into GLUT?

Modernize it to not using de facto deprecated features the likes of display lists. Though I don't know if display lists are really such a sin for rendering a moderate amount of text. They are obviously not part of OpenGL ES; which should be able to render fonts out of the box too. For a full screen in a text editor it sounds like an awful idea (but at that point you might be able to justify using something more like Pango)

It's just not unreasonable for a graphics API to be able to render fonts properly one way or another. Even the more so if we are to really embrace Unicode (open multi-culturalism) sooner or later.

Alfonse Reinheart
09-26-2012, 02:38 AM
If they were looking to be cross platform then they (apparently) have nothing.

Pango. ICU. Cross-platform.

Are we even having the same discussion here? Just because it's not in OpenGL itself doesn't mean it doesn't exist.


Disclaimer: I am not familiar with the status of Unicode fonts with X/Linux or OSX but X has font facilities so it should be able to do its own layouts without every application having a dependency on something like Pango

You're used to the Windows world, where if "the system" doesn't do something, then it may as well not exist. That's not how things happen outside of the Windows world. In the not-Windows world, you use libraries to get things done.

If you use GTK, you have a dependency on Pango because GTK uses Pango for its text layout. It uses LibXML2 for its XML reading, so you have another dependency there. And so on. That's how things work in the not-Windows world: you pick your libraries and use them. Some of these are provided by the system. Some of these are provided by you.

Functionally, there's no difference between having a dependency on Pango and having a dependency on Uniscribe. The only practical difference is that in the Pango case, you have to link to the library explicitly, while in the Uniscribe case, you don't.


It's just not unreasonable for a graphics API to be able to render fonts properly one way or another.

It is very unreasonable.

OpenGL is supposed to be a relatively thin wrapper around graphics hardware, in order to achieve a reasonable abstraction and allow for a reasonable platform-neutral interface to that hardware. OpenGL's job is not to make it easy to do complex things. It's job is to make it possible to do complex things. If something can be layered on top of OpenGL, then it should be.

You won't find any font rendering functions in D3D either, for similar reasons.

Inagawa
09-26-2012, 04:15 AM
I am not working exclusively with Windows, actually. The use of GDI+ (a painful experience as it were) is just temporary.

So how would you gentlemen advise me to continue?
The fonts themselves are drawn with GDI+, but I have no glyph metrics whatsoever - the fontmap generates crude metrics as it goes.

First it takes the default position of the symbol '', and takes note of its height and Y coordinate in a bitmap so it can position smaller and larger characters on the same 'line'.
It's crude, but it actually works. They are positioned in the fontmap's texture with their whitespace intact and therefore it's just a matter of picking out the correct rectangle to draw.
Proud though I may be of this thing actually working, and since my work on the textbox is mostly done (thanks, Alfonse), I now seek an alternative to GDI+ - a cross-platform one if possible.

I've seen the names ICU and Pango floating around, so in the meantime I'll go check what the buzz is all about.


Also, this is how the font looks in the textbox - my eyes hurt from looking at it.

http://imageshack.us/a/img37/2841/screenxbg.png

dukey
09-26-2012, 04:29 AM
I wrote this a while ago



#include <windows.h>
#include <gl\gl.h>
#include <stdio.h>
#include <math.h>

void remapColourRange(UCHAR *data, int numberOfItems) {

for(int i=0; i<numberOfItems; i++) {
data[i] = (data[i] * 255) / 64;
}
}

void copyLine(UCHAR *in, UCHAR *out, int width) {

for(int i=0; i<width; i++) {
out[i] = in[i];
}
}

void flipImage(UCHAR *data, int width, int height) {

//===========
UCHAR *temp;
DWORD offset;
DWORD offset2;
//===========

offset = 0;
offset2 = 0;
temp = new UCHAR[width];

for(int i=0; i<height/2; i++) {

offset = ((width+3) & ~3) * i;
copyLine(data+offset,temp,width); // copy bottom line

offset2 = ((width+3) & ~3) * (height-i-1);
copyLine(data+offset2,data+offset,width); // copy top line to bottom

copyLine(temp,data+offset2,width); // temp line to top
}

delete []temp;
}

void convertLine(UCHAR *in, UCHAR *out, int width) {

for(int i=0; i<width*4; i+=4) {
out[i+0] = 255;
out[i+1] = 255;
out[i+2] = 255;
out[i+3] = in[i/4];
}
}

void convertToRGB(UCHAR *in, UCHAR *out, int width, int height) {

//==========
int offset;
int offset2;
//==========

offset = (width+3) & ~3;
offset2 = (((width*4)+3) & ~3);

for(int i=0; i<height; i++) {
convertLine(in+(offset*i),out+(offset2*i),width);
}
}

BOOL createFont(HDC hdc, DWORD first, DWORD count, DWORD listBase) {

//===========================
GLYPHMETRICS gm;
MAT2 mat2;
DWORD size;
UCHAR *data;
UCHAR *RGBData;
//===========================

// safety checks

if(!count) return FALSE;
if(!hdc) return FALSE;

// initiate variables

size = 0;
data = NULL;
RGBData = NULL;
memset(&gm,0,sizeof(GLYPHMETRICS));

// identity matrix

memset(&mat2, 0, sizeof(mat2));
mat2.eM11.value = 1; mat2.eM21.value = 0;
mat2.eM12.value = 0; mat2.eM22.value = 1;

glPushAttrib(GL_PIXEL_MODE_BIT);
glPixelStorei(GL_UNPACK_ALIGNMENT,4);

for(DWORD i = 0 ; i< count; i++) {

glNewList(listBase+i,GL_COMPILE);
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT);

// get size of the structure first

size = GetGlyphOutline(hdc,first+i,GGO_GRAY8_BITMAP, &gm, 0, NULL, &mat2);
if(size == GDI_ERROR) { glEndList(); continue; }

if(size) {

data = new UCHAR[size];

GetGlyphOutline(hdc,first+i,GGO_GRAY8_BITMAP,&gm,size,data,&mat2);

remapColourRange(data,size);
flipImage (data,gm.gmBlackBoxX,gm.gmBlackBoxY);

RGBData = new UCHAR[(((gm.gmBlackBoxX*4)+3) & ~3) * gm.gmBlackBoxY ];

convertToRGB(data,RGBData,gm.gmBlackBoxX,gm.gmBlac kBoxY);
}

glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glBitmap (0,0,0,0,(GLfloat)gm.gmptGlyphOrigin.x,(GLfloat)gm .gmptGlyphOrigin.y-(GLfloat)gm.gmBlackBoxY,NULL); //incriment raster position
if(size) glDrawPixels(gm.gmBlackBoxX,gm.gmBlackBoxY, GL_RGBA, GL_UNSIGNED_BYTE, RGBData);
glBitmap (0,0,0,0,(GLfloat)-gm.gmptGlyphOrigin.x,-((GLfloat)gm.gmptGlyphOrigin.y-(GLfloat)gm.gmBlackBoxY),NULL); //incriment raster position
glBitmap (0,0,0,0,(GLfloat)gm.gmCellIncX,(GLfloat)gm.gmCell IncY,NULL); //incriment raster position

glDisable (GL_BLEND);

glPopAttrib ();
glEndList ();

delete []data;
delete []RGBData;
}

glPopAttrib ();

return TRUE;
}


It works as a drop in replacement for wglfontbitmaps. Proper anti-aliased fonts for win32. Opengl 1-2 support.
It's not especially fast because it uses gldrawpixels, which doesn't seem to be very fast. But it works fine nonetheless.

If you use it credits to me please :)

def
09-26-2012, 07:07 AM
Why is nobody discussing FTGL, have I been missing something?

FTGL is a free cross-platform Open Source C++ library that uses Freetype2 to simplify rendering fonts in OpenGL applications. FTGL supports bitmaps, pixmaps, texture maps, outlines, polygon mesh, and extruded polygon rendering modes.

michagl
09-26-2012, 10:02 PM
You're used to the Windows world, where if "the system" doesn't do something, then it may as well not exist. That's not how things happen outside of the Windows world. In the not-Windows world, you use libraries to get things done.

Just for the record I work with both but I do consider them to be wildly different types of operating environments filling ultimately different needs. I use Cygwin a lot with Windows but there is nothing in the Linux world that really encourages the development of monolithic platforms for Linux.


If you use GTK, you have a dependency on Pango because GTK uses Pango for its text layout. It uses LibXML2 for its XML reading, so you have another dependency there. And so on. That's how things work in the not-Windows world: you pick your libraries and use them. Some of these are provided by the system. Some of these are provided by you.

Not to nitpick but I am aware of that. I don't use GTK for the record. But I do appreciate glib. But I've never developed a windowed app for X (so I don't know what is required to integrate with the window managers; full disclosure)


Functionally, there's no difference between having a dependency on Pango and having a dependency on Uniscribe. The only practical difference is that in the Pango case, you have to link to the library explicitly, while in the Uniscribe case, you don't.

Exactly. It's not a project (sourcecode) dependency. It's under the hood.


OpenGL is supposed to be a relatively thin wrapper around graphics hardware, in order to achieve a reasonable abstraction and allow for a reasonable platform-neutral interface to that hardware. OpenGL's job is not to make it easy to do complex things. It's job is to make it possible to do complex things. If something can be layered on top of OpenGL, then it should be.

Well yeah. OpenGL doesn't open any file formats. Fonts are files. So obviously rendering text is not implemented at the level of the OpenGL spec. But nevertheless it's important to make graphics accessible and text mindlessly multilingual. IMO it's pretty ridiculous that a consumer card cannot draw lines in 2012. But even I will admit that line drawing is less integral than drawing text, and there are legitimate, albeit pretty ridiculous, reasons for not implementing line drawing in hardware. Still it should be standard, especially as GPUs and CPUs become more and more integrated in mainboards. We shouldn't be having a discussion about drawing text in 2012. Printf like drawing should not introduce a new library to a project. That's just my opinion.


You won't find any font rendering functions in D3D either, for similar reasons.

Search for D3DX.

michagl
09-26-2012, 10:11 PM
I am not working exclusively with Windows, actually. The use of GDI+ (a painful experience as it were) is just temporary.

So how would you gentlemen advise me to continue?

Yeah definitely. But you might consider different strategies depending on what your ultimate goals are. I am definitely following this thread, and it will definitely influence my work. I hope you don't mind my taking advantage or it.

You basically would need to say what platforms you are targeting. What are you wanting to do with it. Is i18n important. Is it an opensource or closed source project. Is it of limited scope etc.

Depending on your answers a good answer might be yeah, if it looks good to you and it works, then that's that right? Or otherwise you might want to hang around and see what doesn't rise out of these ashes.

PS: If you are not planning on leaving planet Windows I think there probably are some things you can do to make things easier and nicer.




It works as a drop in replacement for wglfontbitmaps. Proper anti-aliased fonts for win32. Opengl 1-2 support.
It's not especially fast because it uses gldrawpixels, which doesn't seem to be very fast. But it works fine nonetheless.

If you use it credits to me please http://www.opengl.org/discussion_boards/images/smilies/smile.png


Why is nobody discussing FTGL, have I been missing something?

FTGL is a free cross-platform Open Source C++ library that uses Freetype2 to simplify rendering fonts in OpenGL applications. FTGL supports bitmaps, pixmaps, texture maps, outlines, polygon mesh, and extruded polygon rendering modes.

Just wanted to say thanks for these two posts.

EDITED: Also as for FTGL. I do worry about these kinds of projects not supporting particular (widely used; non proprietary) font file formats for quasi-political reasons. But on the other hand I would not be surprised if there are file formats and fonts exclusively used in the Linux world. In which case there is probably a strong argument for doing things in more than one way in order to make all the fonts anyone might want to use just work so that they will be happy :(

Alfonse Reinheart
09-26-2012, 11:44 PM
It works as a drop in replacement for wglfontbitmaps. Proper anti-aliased fonts for win32. Opengl 1-2 support.

The whole point of wanting to replace wglFontBitmaps (besides potential performance issues) is to not use removed functionality like glDrawPixels and display lists.


Why is nobody discussing FTGL, have I been missing something?

Because it's 8 years old and clearly no longer being supported.


IMO it's pretty ridiculous that a consumer card cannot draw lines in 2012.

You can draw lines in consumer cards just fine.


Printf like drawing should not introduce a new library to a project.

This makes no sense. You don't want to use Pango to do text layout, and you don't want to use FreeType2 to do glyph creation and font processing. But you don't mind if something else uses them, if it's "under the hood".

OK, but that something else... will be a library. Which, if you're not already using in your project, will have to be introduced to it. The very thing you say you don't want to do.

So I really don't understand what it is you're looking for. It sounds to me like you want some magical, "Do everything I want" library to poof into being. You want FreeGLUT or whatever to simply solve all of your problems as you get them.

That's not going to happen; the sooner you accept that, the better.


Search for D3DX.

I did. According to Wikipedia, it's Deprecated in the Win8 SDK. The only part that survives are the math functions that form the core of DirectX Math.

Also, D3DX is not part of D3D and it never was. It is a new library that you explicitly have to introduce to a project separately from D3D.

Inagawa
09-28-2012, 06:51 AM
michagl: Well, the story is basically that I need a way of not only rendering the glyphs in good quality, but I also need all the glyph metrics, so I can position the glyphs individually.
GDI+ vomits some kind of metrics, but they are unusable.

I'd actually like to avoid using any external libraries at all if possible - I happen to be using C# and OpenTK, so any external library might be a big problem for me.

Alfonse Reinheart
09-28-2012, 08:37 AM
So let me get this straight. You want a cross-platform glyph rendering solution. But you don't want to use an "external library" to do it (even though GDI+ is an external library). So... how exactly do you expect this to happen?

In general, the non-Windows world renders its glyphs through FreeType2. But that's an external library.

Inagawa
09-28-2012, 09:17 AM
I said I'd like to avoid using external libraries, but I will use them if there's no other way. And GDI+ may be an external library to you (C++), but not to me - it's part of .NET.

I'll have a look at FreeType2, it looks sweet. Thanks for the recommendation, I'll post here later on how it worked out.

michagl
09-28-2012, 11:47 PM
You can draw lines in consumer cards just fine.

Not in my experience. If you are using a normal consumer card for playing games changes are the lines will be broken and irregular when you use a line drawing API. This is still the case on a 1400$ gaming laptop that is going on 7yrs old. And its the case on an ATOM+ION2 (mainboard, cpu, and gpu in one) that is about 2yrs old now that I purchased as a backup. Actually the laptop has defect that kills the graphics modules, but I quit replacing them with the same model (because it became too expensive) and I don't know if I've done anything with line rendering since. Prior to around the times programmable GPUs became the norm drawing lines just worked. Though I tended to have workstation cards back then. Maybe nowadays you need an extension or something.


This makes no sense. You don't want to use Pango to do text layout, and you don't want to use FreeType2 to do glyph creation and font processing. But you don't mind if something else uses them, if it's "under the hood".

Sure. Whenever you use a library you don't know what it is going to do under the hood. It's an abstraction layer. If you want to do something like a publishing app then you might want a lot of control. But if you just need to display text you don't want to complicate things, have to write a wrapper around a competing library that may not even be supported a few years down the line. You want something minimal and standard that can be relied on in the long term. Just displaying text should be as simple as writing text to a file in 2012. Since the ways to do that are not very mature on desktop platforms other than Windows there is no standard way to do it apparently. So we are just trying to figure out the best way in the meantime the way I see it.


So I really don't understand what it is you're looking for. It sounds to me like you want some magical, "Do everything I want" library to poof into being. You want FreeGLUT or whatever to simply solve all of your problems as you get them. Yeah that's how we do it. Ex. You don't program a software rasterizer in 2012 and you don't expect to.


That's not going to happen; the sooner you accept that, the better.
It will happen but that's not the point. It's a shame it hasn't happened yet, otherwise this thread would be unnecessary. We have something like gettext to do translation. Drawing text should be as simple and as commonplace. It is an additional dependency which almost everything already has as a dependency, but its minimal and entrenched and well understood. Text is a basic currency of information exchange. It should be provided at the system level and integrated into OpenGL. If we lived in a world where you didn't need more than 65535 characters to render all of the symbols of all of our languages etc... if we just need ASCII things would be different. But the guts of Unicode need to be under the hood and easy to access so that we can easily communicate with it. It's a travesty IMO but again just an opinion.


I did. According to Wikipedia, it's Deprecated in the Win8 SDK. The only part that survives are the math functions that form the core of DirectX Math.

I think D3D is deprecated IMO because its not compatible with XP past D3D9. Microsoft had to bring back XP after it declared it dead because it did not anticipate netbooks and nettops and it doesn't have anything for those class of PCs in the works. I love these things because I can buy a computer for the same price I used to pay for a cpu, and a mainboard, and a gpu, and presumably they are just going to get cheaper and cheaper... that's a huge market to neglect. I have almost no expensive habits in my life nowadays.


Also, D3DX is not part of D3D and it never was. It is a new library that you explicitly have to introduce to a project separately from D3D.

It's an extension layer for D3D. It uses the same interfaces. It's analagous to GLUT. I think there was something else simply called Glu, but I forget, it's been so long. I did not tend to use either. But that was around the turn of the century. Most of all D3DX is something the end user installs separately from your application and if they play video games will almost always already have installed. On Windows that is important, even though in the Linux world you have package management (that makes DLL hell look like a picnic)

michagl
09-29-2012, 12:03 AM
michagl: Well, the story is basically that I need a way of not only rendering the glyphs in good quality, but I also need all the glyph metrics, so I can position the glyphs individually.
GDI+ vomits some kind of metrics, but they are unusable.

I'd actually like to avoid using any external libraries at all if possible - I happen to be using C# and OpenTK, so any external library might be a big problem for me.

In my opinion the only worthwhile technologies Microsoft has ever developed are Win32 and COM (COM is slowly replacing Win32 completely which is probably for the best; D3D is an example of COM) and if you look under the hood of everything that MS churns out, MFC, ATL, GDI+, .Net, C# (and its 3 or 4 molts), all kinds of new stuff for Win8, and everything I've left out, of which there is likely many because I am very dismissive of all of them because like I was trying to say if you look under the hood you find out that these are all wrappers around Win32 and COM most of which have a very short life cycle. But I understand that MS requires the use of C# I think for some things like entry level Xbox development.

I would never use one of Microsoft's static OOP APIs like MFC and GDI+. All of the fonts in Windows are based on a class of functions that are equivalent to DrawText in its Win32 and D3DX variety. It should be possible to generate metrics with these if they are provided... but I am wondering why you are mixing C# and OpenGL. That seems like an unusual pattern.

Actually I forgot. GDI is actually just the graphics APIs of Win32. So it's definitely not deprecated. That means it's just GDI+ that is solidly deprecated. GDI+ is just an MFC like version of GDI in my experience. So probably you are already familiar with this family of functions in one form or another...

http://msdn.microsoft.com/en-us/library/windows/desktop/dd144821%28v=vs.85%29.aspx

EDITED: Search for "Font and Text Functions" (since microsoft.com links have a lifespan of only a few months)

I think that is everything, but I may be wrong.

The metrics should not be unusable. You are probably just not doing something right (unfortunately we are stuck with Microsoft's "documentation" and short term memory until someone is able to topple this giant; and unfortunately compared to MS's competitors MS really looks more and more like the friendly giant nowadays)

MS calls these APIs legacy (not the same as deprecated) but the truth is everything boils down to Win32 or COM and COM does not yet do everything Win32 can and it certainly can't (and never will) on XP and all of Microsoft's non-legacy (read: deprecated or-soon-to-be wrapper) APIs are always supplanted after a year or two so they are really not worth the investment if you envision your code being useful ~2 years from whenever.

Alfonse Reinheart
09-29-2012, 07:56 AM
Not in my experience. If you are using a normal consumer card for playing games changes are the lines will be broken and irregular when you use a line drawing API.

Define "broken and irregular". Lines are drawn. They may not be pretty, but they're drawn from point A to point B.


It's an extension layer for D3D. It uses the same interfaces. It's analagous to GLUT.

No it isn't. GLUT is a toolkit for creating and managing OpenGL windows, with a few ancillary functions for doing useful things. And though D3DX provides many features, conspicuously absent from that feature list is a simple way to create and manage a D3D window. Similarly, D3DX's primary features are math functions, image loading, meshes loading, and shader/effects loading and management, none of which you will find in GLUT.

Please stop trying to pretend that two libraries that have completely different purposes are in any way comparable just because they're named similarly.


GDI+ is just an MFC like version of GDI in my experience.

:doh:

In the future, please take the time to do some research (http://en.wikipedia.org/wiki/GDI%2B#Version_history) before forming an opinion and spreading misinformation.

mhagain
09-29-2012, 08:56 AM
D3DX is more analogous to GLU. The functionality provided by each library may differ, but the underlying intent is much the same. So you'll find routines for quadrics, tesselation, some limited matrix work, some helpers for texture loading in GLU, and you'll find a whole bunch of other routines in D3DX, some of which overlap, but in both cases they supplement the core API (by wrapping functionality, by providing some handy helper routines, or by providing an implementation of some things that you would otherwise need to write code for yourself) rather than being an actual part of it. It's perfectly possible to write a GL program without even touching GLU and it's perfectly possible to write a D3D program without even touching D3DX.

Re: drawing lines - both OpenGL and D3D provide support for lines (lines are even still a core primitive topology type in D3D11), but the problem may occur when you talk about lines wider than 1 pixel, which may or may not be supported in hardware by consumer cards.

Inagawa
09-29-2012, 04:33 PM
I am proud to report that so far I've been successful. I am now rendering text with subpixel filtering and the quality seems awesome so far.
I've also made some drastic changes in design of the fontmap and sped it up.

The old fontmap could generate about 13,000 glyphs in about 13 seconds, while the new one can generate 15,416 glyphs in 1.32 seconds.

I'll have to do quite a few tests to determine if everything is okay, so I'll probably post some update tomorrow.

michagl
09-30-2012, 02:01 AM
Define "broken and irregular". Lines are drawn. They may not be pretty, but they're drawn from point A to point B.

Broken, there are sometimes pixel wide gaps in the middle of a single line. Irregular the corners do not mate sometimes at all. In my experience you are only guaranteed the suggestion of lines. Though there may be cards that flat refuse to draw lines (I haven't researched it)

Sometimes it seems like the run-length is cutoff so that the lines are not even locally straight. I started noticing this with OpenGL a long time ago, and I was told, and it was common knowledge at the time that line drawing was out if you have a sub-workstation video adapter.


No it isn't. GLUT is a toolkit for creating and managing OpenGL windows, with a few ancillary functions for doing useful things. And though D3DX provides many features, conspicuously absent from that feature list is a simple way to create and manage a D3D window. Similarly, D3DX's primary features are math functions, image loading, meshes loading, and shader/effects loading and management, none of which you will find in GLUT.

I've worked with Glut or maybe something similar called Glu that does all kinds of D3DX like stuff, drawing quadrics and primitives for example. This is nitpicking. An extension framework can implement whatever kinds of extensions that seem to be necessary or desirable.

http://en.wikipedia.org/wiki/OpenGL_Utility_Library

This seems like a meta argument / disservice to the thread to me.


Please stop trying to pretend that two libraries that have completely different purposes are in any way comparable just because they're named similarly.

What is named similarly? Nvm. I really don't care:tired:




:doh:

In the future, please take the time to do some research (http://en.wikipedia.org/wiki/GDI%2B#Version_history) before forming an opinion and spreading misinformation.

If I had to do research before opening my mouth I never would. But for the record anything I've ever seen GDI+ used for you can do with GDI with a little extra work. I don't doubt there may be exclusive things it can do. But then it would seem odd to deprecate it without deprecating GDI or migrating the features into GDI.

I did happen to inadvertently do some research into C#. I must admit I really don't understand it other than it looks like a way for Microsoft to alienate itself away from C++. There is an ECMA standard for it oddly enough even though only MS implements it. I always assumed it was compatible with "managed" (Microsoft extensions) C++ and C++ itself. I'm assuming it can dynamically link to C/C++ libraries, otherwise it would be a total island of unusability. Either way I apologize for lumping C# into the above post. I think I meant managed C++. I could not figure out what C# is good for; and am even less inclined to use if for anything now. Being a beast of Microsoft it seems strange to breed it with OpenGL... I'm intrigued at least:)



Edited: @ mhagain (http://www.opengl.org/discussion_boards/member.php/14534-mhagain), sorry I did not notice the two posts on the top of this page. Unfortunately I can't do a ton of tests with different hardware to get an idea about the state of 1px wide line drawing. I am pretty sure I am not hallucinating the bottom falling out of line drawing since a half a decade or more years back. I've always assumed the girth of papers describing ways to draw lines without line drawing was an attempt to win back this lost functionality on consumer hardware and that the support for line drawing was worse than just being slow. Anyway it's offtopic.

@Inagawa. Are you planning on publishing your source code? Are you generating glyphs on demand? A lot of the time a font will have a lot more symbols than you actually need, and a lot more than will fit on a texture. I wonder myself if the D3DX DrawText implementation draws its vector fonts to a texture or if it just draws them as a flat 3D mesh. The D3DX docs kind of suggest they are drawn to a texture as I recall, but without looking at them (so sue me) it could also be interpreted as drawing to a vertex/index buffer.

Inagawa
09-30-2012, 06:50 AM
My fontmap doesn't just pick some random glyphs and slap them on a texture, you tell it which exact symbols you need represented (there are a few constants in place so you don't need to write them by hand) and it bin-packs as many as it can on a texture (the size of which you specify). If there isn't enough space on the texture, it simply creates another one and continues there. You then just request all the info by calling a simple GetGlyph() function which returns all of the information that you need to successfully position and render the glyph.
You can even update the texture with new glyphs as you go, even after they are made into an OpenGL texture.

Also, to defend C# - it's not a microsoft-exclusive language; since the ECMA standard, Mono developed C# compilers for all the other platforms you could ever need. C/C++ interop is achieved either through P/Invoke system or by writing a C++/CLI wrapper that can be accessed from C#.

Edit: Success, Pango is now the backend for rendering and measuring the glyphs. Now just to figure out where to set the filtering.

thokra
10-01-2012, 02:06 AM
If I had to do research before opening my mouth I never would.

OT: Any chance you're a Fox News or MSNBC anchor? :doh:

Inagawa
10-01-2012, 05:38 AM
Why all the hostility towards him?

Alfonse Reinheart
10-01-2012, 08:06 AM
Why all the hostility towards him?

He admitted to not bothering to actually learn things before trying to make claims about them. That kind of thinking deserves hostility.

I seem to recall a quote, "Better to remain silent and be thought a fool, than to open your mouth and remove all doubt."

michagl
10-03-2012, 03:19 AM
OT: Any chance you're a Fox News or MSNBC anchor? :doh:

Yeah I am paid to post in forums. And whenever I am asked a question, I say, excuse me, I don't want to be rude or anything, but can you wait for me to do some research :)


Why all the hostility towards him?

Because this is the internet and everyone is welcome to participate :)


Also, to defend C# - it's not a microsoft-exclusive language; since the ECMA standard, Mono developed C# compilers for all the other platforms you could ever need. C/C++ interop is achieved either through P/Invoke system or by writing a C++/CLI wrapper that can be accessed from C#.

I see. Someone should somehow add Mono to the version table on Wikipedia. It gives the wrong impression. So much for doing research!

I did look back to find Bjarne's take on C#. He suggested it's proprietary (and lamentable) in his site's FAQ.

I did notice BTW that wglUseFontOutlines returns metrics in the form of GLYPHMETRICSFLOAT. They are not super sophisticated but are probably acceptable for most applications (without researching and writing a program to see for myself; irresponsible of me I realize)

Anyway wglUseFontBitmaps doesn't seem to do this so it's easy to miss, but it isn't clear that wglUseFontOutlines can do bitmapped fonts. And the docs explicitly say "TrueType" which I assume limits fonts to vector formats not limited to .ttf.

This is why it would be nice to have standards.


I seem to recall a quote, "Better to remain silent and be thought a fool, than to open your mouth and remove all doubt."

Said the (edited: incredibly vain of dubious character) fool :)


PS: How many posters here are interested in rhetoric vs fonts? I for one would like to keep the discussion going because as I've stated I am still not personally convinced what to do about fonts vis a vis OpenGL and am interested in the experiences of others.

thokra
10-03-2012, 03:35 AM
And whenever I am asked a question, I say, excuse, but, I don't want to be rude or anything, but can you wait for me to do some research. [..] Because this is the internet and everyone is welcome to participate :)

OT: So, you want participation without qualification? Don't we have enough Romneys already?

Inagawa
10-03-2012, 12:01 PM
Don't say his name, let's refer to him as "the guy who believes he gets to play god on his own planet after he dies". A little long, though.

Now, to the fonts. I have managed to get Pango up and rolling, so now it's just a question of programming some textbox class and test how well the metrics hold up under a real stress. I have also noticed that there are a lot of strange symbols in the UTF-8 ranges. Some symbols are kind of "associative" in that they stick to other symbols. I am yet unsure if my fontmap will be able to represent those symbols, for I haven't made much research on that.

michagl
10-04-2012, 11:51 AM
OT: So, you want participation without qualification? Don't we have enough Romneys already?

Well for the record what I was trying to say is even immature and impractical people are allowed to be mean on the internet. Inclusion and participation is usually a good thing; except when it's participation in generally intolerant and psychopathic behavior. I don't think Romney believes in participation since he participated in a debate the other night that excluded candidates that are on the ballot in most of the states he would like to represent in the executive office. Funny that's the same reason I can't in good conscience participate in voting for our presidents. So I guess that makes me unqualified to be a citizen. Still I participate. Who in their right mind thinks about such things much less drags them into online discussion forums I wonder...

The nice thing about online forums is no matter how ugly the baring of teeth no one has yet to die at the hands of a crazed gunman mid post. Most of the meanness you find online is probably just a reflection of the pure frustrated impotency you are faced with when you try to lash out violently at a computer monitor :)


Some symbols are kind of "associative" in that they stick to other symbols. I am yet unsure if my fontmap will be able to represent those symbols, for I haven't made much research on that.

Those would have to be composited. But by god if you are loading up Pango surely it is able to do all of the necessary drawing?!

thokra
10-04-2012, 12:38 PM
OT: This forum isn't about tolerance or acceptance. It's about helping people with questions regarding OpenGL or topics connected to OpenGL. If in the course of answering a question, or participation in a discussion spawned by said question, you come up with incorrect statements, you should correct that sentence yourself or at least have the decency to accept corrections from others. That's the only reason why I cam up with the new network comparison. Since I polluted this thread enough with my perceived rants I'm simply gonna stop here with the suggestion, that in the future you either research stuff that you want to comment on, say that you don't know about something if you can't answer a question, or simply don't say anything at all. Thanks.

Inagawa
10-05-2012, 07:09 AM
Those would have to be composited. But by god if you are loading up Pango surely it is able to do all of the necessary drawing?!

Where is the fun in doing things like every other bloke? I want to see if my fontmap is possible, for it should theoretically perform much better. I will obviously use Pango itself to render text if I find the fontmap to be impractical or broken.

Inagawa
10-05-2012, 11:06 AM
Success, brothers!

http://imageshack.us/a/img441/6105/screentextboxv4.png

The color is (0.15, 0.15, 0.15) so the contrast isn't that painful on the eyes. What do you guys think, could you read text like this without problems?

I have had no luck finding the function with which to set the filtering, so I assume it's some antialias_gridfit one - I'd like the subpixel one (I think it would make the text less painful to read). Does anyone know where I might look?

Inagawa
10-07-2012, 07:03 AM
Here's how it looks after a complete rewrite (word-wrapping words but not spaces, some optimizations) if anyone still cares.

http://imageshack.us/a/img337/1004/screen2rg.png

This is how the quads are positioned: http://imageshack.us/a/img855/5263/screen2ds.png

michagl
10-09-2012, 03:32 PM
OT: This forum isn't about tolerance or acceptance. It's about helping people with questions regarding OpenGL or topics connected to OpenGL. If in the course of answering a question, or participation in a discussion spawned by said question, you come up with incorrect statements, you should correct that sentence yourself or at least have the decency to accept corrections from others. That's the only reason why I cam up with the new network comparison. Since I polluted this thread enough with my perceived rants I'm simply gonna stop here with the suggestion, that in the future you either research stuff that you want to comment on, say that you don't know about something if you can't answer a question, or simply don't say anything at all. Thanks.

Who was it that brought it up? I am just trying to fit in. You will survive either way :)

michagl
10-09-2012, 03:36 PM
Here's how it looks after a complete rewrite (word-wrapping words but not spaces, some optimizations) if anyone still cares.

http://imageshack.us/a/img337/1004/screen2rg.png

This is how the quads are positioned: http://imageshack.us/a/img855/5263/screen2ds.png

Yeah I care of course. But I can only make a point to read this forum off and on. So this is using your customized technique? Or Pango? Does Pango let you only load the pieces (library modules) you need?

So it looks like you are aiming for either a text editor or a very wordy game or reader or something?

Inagawa
10-10-2012, 11:29 AM
It's the result of this code:


_renderer = new Renderer(this, 6500);
_renderer.MapBuffer();

var fontMap = new FontMap(_renderer, new Size(512, 512));
fontMap.AddGlyphSet(FontMap.BasicLatin, "Times New Roman", 10, Style.Normal, Weight.Normal, Underline.None);
fontMap.AddGlyphSet(FontMap.BasicLatin, "Times New Roman", 16, Style.Normal, Weight.Normal, Underline.None);
fontMap.GenerateFontMap();

// Renderer, FontMap, MaxWidth, MaxHeight, FontName, FontSize, FontStyle, FontWeight, FontUnderline, PosX|Y|Z
_block = new Block(_renderer, fontMap, 790, 600, "Times New Roman", 16, Style.Normal, Weight.Normal, Underline.None, 0, 0, 0);
_block.SetText(Text, Block.Alignment.Center);

So, basically the fontmap uses Pango to paint all the glyphs that you need (e.g., FontMap.BasicLatin) into a dynamically managed buffer.
The rendered glyphs are sorted with an offshoot of the Cygon Bin Packer and then an opengl texture is generated with "GenerateFontMap()" call.

Well, after generating the texture you can access any glyph information by calling


glyphInfo = _fontMap.GetGlyph(Character, FontName, Size, Style, Weight, Underline);

The glyphInfo contains everything you need to successfully render a single glyph (e.g., position on the texture, index of the texture, bearingX|Y, advanceX|Y, etc).

It's quite neat, but the dependency on Mono makes it all quite ... distasteful. On the other hand, I doubt you'll find faster dynamic text. Sure it may suffer against static text, but for my uses this was what I needed.

michagl
10-13-2012, 08:32 AM
^Can comment on which constructs in the code above belong to what libraries?

PS: I've subscribed to this thread (should have already) just now and will make a point to report back here after I am able to figure the best solution for my needs. I recommend anyone who wants to hear what I come up with subscribe too because it may well come a year from now :)

My hope is to come up with something that apes DrawText in ease of use but is portable and serves as many non-proprietary (or de facto so) fonts as possible be they compatible with DrawText or not. It's a nut I will have to crack sooner or later if a proper solution doesn't boil up in the meantime. My theory is rendering text for things like games should be brain dead simple regardless of your platform.

Inagawa
10-14-2012, 07:47 AM
The Renderer uses only OpenTK, FontMap uses OpenTK, Pango and Cairo. The block closely uses FontMap. I can PM you the source to the classes you want to see, or I can post them here if anyone else is interested. But as you know, it's all in C# (and I guess all of you are using C++).

Also, this is by no means completed. As far as fontmap generating goes, the GDI-based fontmap supports all installed fonts and fonts from file and memory. It's also able (thanks to GDI+) to render glyphs from other fonts if they don't exist in the specified font. The downside are the simulated glyph metrics. Since I had to fake them, the text isn't aligned very well (the reason I abandoned it, after all). The Pango-based fontmap only supports installed fonts and cannot substitute glyphs, but has better quality of text and pixel-perfect glyph alignment. It is also much more memory efficient and 10x faster.

The Block is programmed to work with the newer, Pango-based fontmap, but it's easy to use it with the older fontmap.

michagl
10-16-2012, 11:37 AM
^So is it safe to assume that all of the code above is your own (wrapped around the public libraries we are negotiating) ?

FYI: It should not be necessary to use "simulated glyph metrics" with the GDI based fonts. I remember DrawText will ignore leading and trailing spaces in lines of text so I had to manually calculate the metrics to get correct results. With Unicode there are more than a few kinds of spacing characters, and I did have trouble making sense of the metrics, but eventually I figured them out. They are confusing maybe, but surely they are the same metrics Windows uses under the hood. You just have to spend more time with them I suspect.

Also it's disappointing if Pango requires fonts to be installed. I find it's very helpful to go around the installed fonts with games. The software I have been working with for a while now originated in Japan, and to make it work as intended it's easiest to just deliver the core fonts with it since many people do not have Windows' Japanese fonts installed (Unicode fonts don't really count) plus game authors and translators like to use custom fonts and asking the end user to install fonts for a game on demand is really bothersome, plus the font will remain installed after the game is no more.

PS: I suspect the best approach here would be to use GDI as much as possible on Windows. And do whatever is necessary on Linux with X... possibly going low-level if need be. If Pango will only do installed fonts on Windows it's not going to give you anything (critical) that GDI can't do, so it's probably not worth the dependency in my book. Probably implementing something like ID3DXFont that works with OpenGL (basically what you were originally doing) is a good way to go if the fonts must be displayed with OpenGL.

Inagawa
10-18-2012, 10:05 AM
Usage of installed fonts is not Pango's limitation, but merely my own. I don't care for portable fonts enough to bother with converting the .NET Font object to the Pango Font object. And yes, all the code is mine.

Also, I tried quite a bit of GDI+ measuring functions, but it always returned padding and other stuff that makes it (to me) impossible to get the exact size of the glyph. In the end, I have simply settled for a loop that maps the area the glyph is occupying. Although that was also one of the slowdowns I got with the GDI+ version. No such thing is necessary with Pango.



/// <summary>
/// Measures the symbol in the buffer with pixel-precision.
/// </summary>
/// <returns>The exact region that the symbol occupies, in pixels</returns>
internal unsafe Rectangle MeasureSymbolInBuffer()
{
// Create variables to hold the coordinates
var lowestX = _bufferBitmap.Width;
var lowestY = _bufferBitmap.Height;
var highestX = 0;
var highestY = 0;

// Lock the bits into memory
var bitmapData = _bufferBitmap.LockBits(new Rectangle(0, 0, _bufferBitmap.Width, _bufferBitmap.Height),
ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

// Get the buffer pointer
var buffer = (Byte*) bitmapData.Scan0.ToPointer();

// Find the exact span of pixels this symbol occupies
for (int j = 0; j < _bufferBitmap.Width*4; j += 4)
{
for (int i = 0; i < _bufferBitmap.Height*4; i += 4)
{
// Only stop at the pixels that are not transparent
if (buffer[(i*_bufferBitmap.Width) + j + 3] != 0)
{
var x = j/4;
var y = i/4;

if (x < lowestX)
{
lowestX = x;
}

if (y < lowestY)
{
lowestY = y;
}

if (x > highestX)
{
highestX = x;
}

if (y > highestY)
{
highestY = y;
}
}
}
}

// Unlock the bits
_bufferBitmap.UnlockBits(bitmapData);

// In case this is the first time this is run, acquire data for the default
if (_defaultSize.Y == 0 && _defaultSize.Height == 0)
{
_defaultSize.Y = lowestY;
_defaultSize.Height = highestY;
}

// If these two coordinates are less than the default, they have to be
// set to the default, otherwise symbols like underscores would be drawn
// at the very top because of their minimal height, same for small letters
if (lowestY > _defaultSize.Y)
{
lowestY = _defaultSize.Y;
}
if (highestY < _defaultSize.Height)
{
highestY = _defaultSize.Height;
}

// Shift the higher coordinates so that they point behind the visible pixels
highestX++;
highestY++;

// Create a rectangle from the coordinates
var region = new Rectangle(lowestX, lowestY, highestX - lowestX, highestY - lowestY);

// Clean up used resources
_bufferBitmap.Dispose();
_bufferGraphics.Dispose();

return region;
}

michagl
10-25-2012, 04:47 AM
^So is the above code is reading back the pixels as a way of determining the bounds of the glyphs? Sorry I am just scanning the code.

The metrics provided by GDI are first and foremost for the letter spacing, so that includes padding naturally. Plus there is kerning too if you want things to look really nice. I don't have great memory, but if you wanted like the width between the leftmost and rightmost (or vice versa) non-empty pixel then yeah, that's a little bit unusual. I'd not be surprised if those metrics are available but I would not be surprised if they are not either.

If you include the padding in your textures it would probably remain sufficiently packed together. Sometimes things that seem like savings are really not even worth the time to worry about.


PS: Does Pango not honor all fonts installed by Windows?

Inagawa
10-30-2012, 02:06 PM
Yes, the code scans the buffer bitmap (the size of which is determined by a rough metrics returned by GDI+) pixel by pixel and determines its bounds. It's primitive and it certainly could be improved, but for GDI+ it worked good enough.

And I guess there is a way to get some meaningful numbers, but GDI+ is not worth the time - Pango is much nicer to work with _and_ it's not Microsoft-exclusive.

I don't understand what you mean by "honoring" all fonts. Pango sees all the fonts that are installed and uses them without any problem.

nigels
11-03-2012, 04:46 PM
Not sure if it's been mentioned on this thread already - NV_path_rendering https://developer.nvidia.com/nv-path-rendering

It's vendor-specific, at this point in time.

- Nigel