diff options
Diffstat (limited to 'src/lib/freetype/demo')
-rw-r--r-- | src/lib/freetype/demo/nehe/UFreeType.pas | 326 |
1 files changed, 0 insertions, 326 deletions
diff --git a/src/lib/freetype/demo/nehe/UFreeType.pas b/src/lib/freetype/demo/nehe/UFreeType.pas deleted file mode 100644 index c1243aae..00000000 --- a/src/lib/freetype/demo/nehe/UFreeType.pas +++ /dev/null @@ -1,326 +0,0 @@ -unit UFreeType; - -{$IFDEF FPC} - {$mode delphi}{$H+} -{$ENDIF} - -interface - -uses - FreeType, - gl, - glu, - classes, - sysutils; - -type - // This holds all of the information related to any - // freetype font that we want to create. - TFontData = class - h: single; ///< Holds the height of the font. - textures: array of GLuint; ///< Holds the texture id's - list_base: GLuint; ///< Holds the first display list id - - // The init function will create a font of - // of the height h from the file fname. - constructor Create(const fname: string; h: cardinal); - - // Free all the resources assosiated with the font. - destructor Destroy(); override; - end; - - TFreeType = class - public - // The flagship function of the library - this thing will print - // out text at window coordinates x,y, using the font ft_font. - // The current modelview matrix will also be applied to the text. - class procedure print(ft_font: TFontData; x, y: single; const str: string); - end; - - -implementation - - -// This function gets the first power of 2 >= the -// int that we pass it. -function next_p2 ( a: integer ): integer; inline; -begin - Result := 1; - while (Result < a) do - Result := Result shl 1; -end; - -type - PAGLuint = ^AGLuint; - AGLuint = array[0..High(Word)] of GLuint; - -// Create a display list coresponding to the given character. -procedure make_dlist ( face: FT_Face; ch: byte; list_base: GLuint; tex_base: PAGLuint ); -var - i, j: integer; - width, height: integer; - glyph: FT_Glyph; - bitmap_glyph: FT_BitmapGlyph; - bitmap: PFT_Bitmap; - expanded_data: array of GLubyte; - x, y: single; -begin - // The first thing we do is get FreeType to render our character - // into a bitmap. This actually requires a couple of FreeType commands: - - // Load the Glyph for our character. - if (FT_Load_Glyph( face, FT_Get_Char_Index( face, ch ), FT_LOAD_DEFAULT ) <> 0) then - raise Exception.create('FT_Load_Glyph failed'); - - // Move the face's glyph into a Glyph object. - if (FT_Get_Glyph( face^.glyph, glyph ) <> 0) then - raise Exception.create('FT_Get_Glyph failed'); - - // Convert the glyph to a bitmap. - FT_Glyph_To_Bitmap( glyph, ft_render_mode_normal, nil, 1 ); - bitmap_glyph := FT_BitmapGlyph(glyph); - - // This reference will make accessing the bitmap easier - bitmap := @bitmap_glyph^.bitmap; - - // Use our helper function to get the widths of - // the bitmap data that we will need in order to create - // our texture. - width := next_p2( bitmap.width ); - height := next_p2( bitmap.rows ); - - // Allocate memory for the texture data. - SetLength(expanded_data, 2 * width * height); - - // Here we fill in the data for the expanded bitmap. - // Notice that we are using two channel bitmap (one for - // luminocity and one for alpha), but we assign - // both luminocity and alpha to the value that we - // find in the FreeType bitmap. - // We use the ?: operator so that value which we use - // will be 0 if we are in the padding zone, and whatever - // is the the Freetype bitmap otherwise. - for j := 0 to height-1 do - begin - for i := 0 to width-1 do - begin - if ((i >= bitmap.width) or (j >= bitmap.rows)) then - expanded_data[2*(i+j*width)] := 0 - else - expanded_data[2*(i+j*width)] := byte(bitmap.buffer[i + bitmap.width*j]); - expanded_data[2*(i+j*width)+1] := expanded_data[2*(i+j*width)]; - end; - end; - - - // Now we just setup some texture paramaters. - glBindTexture( GL_TEXTURE_2D, tex_base[integer(ch)]); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - - // Here we actually create the texture itself, notice - // that we are using GL_LUMINANCE_ALPHA to indicate that - // we are using 2 channel data. - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, - 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @expanded_data[0] ); - - //With the texture created, we don't need to expanded data anymore - SetLength(expanded_data, 0); - - //So now we can create the display list - glNewList(list_base+ch, GL_COMPILE); - - glBindTexture(GL_TEXTURE_2D, tex_base[ch]); - - glPushMatrix(); - - //first we need to move over a little so that - //the character has the right amount of space - //between it and the one before it. - glTranslatef(bitmap_glyph^.left, 0, 0); - - //Now we move down a little in the case that the - //bitmap extends past the bottom of the line - //(this is only true for characters like 'g' or 'y'. - glTranslatef(0, bitmap_glyph^.top - bitmap.rows, 0); - - //Now we need to account for the fact that many of - //our textures are filled with empty padding space. - //We figure what portion of the texture is used by - //the actual character and store that information in - //the x and y variables, then when we draw the - //quad, we will only reference the parts of the texture - //that we contain the character itself. - x := bitmap.width / width; - y := bitmap.rows / height; - - //Here we draw the texturemaped quads. - //The bitmap that we got from FreeType was not - //oriented quite like we would like it to be, - //so we need to link the texture to the quad - //so that the result will be properly aligned. - glBegin(GL_QUADS); - glTexCoord2d(0, 0); glVertex2f(0, bitmap.rows); - glTexCoord2d(0, y); glVertex2f(0, 0); - glTexCoord2d(x, y); glVertex2f(bitmap.width, 0); - glTexCoord2d(x, 0); glVertex2f(bitmap.width, bitmap.rows); - glEnd(); - - glPopMatrix(); - glTranslatef(face^.glyph^.advance.x shr 6, 0, 0); - - //increment the raster position as if we were a bitmap font. - //(only needed if you want to calculate text length) - //glBitmap(0,0,0,0,face->glyph->advance.x >> 6,0,NULL); - - //Finnish the display list - glEndList(); -end; - - -constructor TFontData.Create(const fname: string; h: cardinal); -var - library_: FT_Library; - //The object in which Freetype holds information on a given - //font is called a "face". - face: FT_Face; - i: byte; -begin - //Allocate some memory to store the texture ids. - SetLength(textures, 128); - - Self.h := h; - - //Create and initilize a freetype font library. - if (FT_Init_FreeType( library_ ) <> 0) then - raise Exception.create('FT_Init_FreeType failed'); - - //This is where we load in the font information from the file. - //Of all the places where the code might die, this is the most likely, - //as FT_New_Face will die if the font file does not exist or is somehow broken. - if (FT_New_Face( library_, PChar(fname), 0, face ) <> 0) then - raise Exception.create('FT_New_Face failed (there is probably a problem with your font file)'); - - //For some twisted reason, Freetype measures font size - //in terms of 1/64ths of pixels. Thus, to make a font - //h pixels high, we need to request a size of h*64. - //(h shl 6 is just a prettier way of writting h*64) - FT_Set_Char_Size( face, h shl 6, h shl 6, 96, 96); - - //Here we ask opengl to allocate resources for - //all the textures and displays lists which we - //are about to create. - list_base := glGenLists(128); - glGenTextures( 128, @textures[0] ); - - //This is where we actually create each of the fonts display lists. - for i := 0 to 127 do - make_dlist(face, i, list_base, @textures[0]); - - //We don't need the face information now that the display - //lists have been created, so we free the assosiated resources. - FT_Done_Face(face); - - //Ditto for the library. - FT_Done_FreeType(library_); -end; - -destructor TFontData.Destroy(); -begin - glDeleteLists(list_base, 128); - glDeleteTextures(128, @textures[0]); - SetLength(textures, 0); -end; - -/// A fairly straight forward function that pushes -/// a projection matrix that will make object world -/// coordinates identical to window coordinates. -procedure pushScreenCoordinateMatrix(); inline; -var - viewport: array [0..3] of GLint; -begin - glPushAttrib(GL_TRANSFORM_BIT); - glGetIntegerv(GL_VIEWPORT, @viewport); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(viewport[0], viewport[2], viewport[1], viewport[3]); - glPopAttrib(); -end; - -/// Pops the projection matrix without changing the current -/// MatrixMode. -procedure pop_projection_matrix(); inline; -begin - glPushAttrib(GL_TRANSFORM_BIT); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glPopAttrib(); -end; - -///Much like Nehe's glPrint function, but modified to work -///with freetype fonts. -class procedure TFreeType.print(ft_font: TFontData; x, y: single; const str: string); -var - font: GLuint; - h: single; - i: cardinal; - lines: TStringList; - modelview_matrix: array[0..15] of single; -begin - // We want a coordinate system where things coresponding to window pixels. - pushScreenCoordinateMatrix(); - - font := ft_font.list_base; - h := ft_font.h / 0.63; //We make the height about 1.5* that of - - lines := TStringList.Create(); - ExtractStrings([#13], [], PChar(str), lines); - - glPushAttrib(GL_LIST_BIT or GL_CURRENT_BIT or GL_ENABLE_BIT or GL_TRANSFORM_BIT); - glMatrixMode(GL_MODELVIEW); - glDisable(GL_LIGHTING); - glEnable(GL_TEXTURE_2D); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glListBase(font); - - glGetFloatv(GL_MODELVIEW_MATRIX, @modelview_matrix); - - //This is where the text display actually happens. - //For each line of text we reset the modelview matrix - //so that the line's text will start in the correct position. - //Notice that we need to reset the matrix, rather than just translating - //down by h. This is because when each character is - //draw it modifies the current matrix so that the next character - //will be drawn immediatly after it. - for i := 0 to lines.Count-1 do - begin - glPushMatrix(); - glLoadIdentity(); - glTranslatef(x, y - h*i, 0); - glMultMatrixf(@modelview_matrix); - - // The commented out raster position stuff can be useful if you need to - // know the length of the text that you are creating. - // If you decide to use it make sure to also uncomment the glBitmap command - // in make_dlist(). - //glRasterPos2f(0,0); - glCallLists(Length(lines[i]), GL_UNSIGNED_BYTE, PChar(lines[i])); - //float rpos[4]; - //glGetFloatv(GL_CURRENT_RASTER_POSITION ,rpos); - //float len=x-rpos[0]; - - glPopMatrix(); - end; - - glPopAttrib(); - - pop_projection_matrix(); - - lines.Free(); -end; - -end. |