Click here to Skip to main content
15,893,588 members
Articles / Multimedia / OpenGL

OAG Library (OpenGL) Part 2.3 - Drawing 2D Textures Using the Mouse and Programatically

Rate me:
Please Sign up or sign in to vote.
4.29/5 (6 votes)
22 Oct 2010CPOL3 min read 34.1K   1.3K   17  
This tutorial shows library code for 2D Textures and how to draw them programatically using the mouse in an MFC application.
/***************************************************************************/
/*                                                                         */
/*  gxvmort.c                                                              */
/*                                                                         */
/*    TrueTypeGX/AAT mort table validation (body).                         */
/*                                                                         */
/*  Copyright 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K.,       */
/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
/*                                                                         */
/*  This file is part of the FreeType project, and may only be used,       */
/*  modified, and distributed under the terms of the FreeType project      */
/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
/*  this file you indicate that you have read the license and              */
/*  understand and accept it fully.                                        */
/*                                                                         */
/***************************************************************************/

/***************************************************************************/
/*                                                                         */
/* gxvalid is derived from both gxlayout module and otvalid module.        */
/* Development of gxlayout is supported by the Information-technology      */
/* Promotion Agency(IPA), Japan.                                           */
/*                                                                         */
/***************************************************************************/


#include "gxvmort.h"
#include "gxvfeat.h"


  /*************************************************************************/
  /*                                                                       */
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  /* messages during execution.                                            */
  /*                                                                       */
#undef  FT_COMPONENT
#define FT_COMPONENT  trace_gxvmort


  static void
  gxv_mort_feature_validate( GXV_mort_feature  f,
                             GXV_Validator     valid )
  {
    if ( f->featureType >= gxv_feat_registry_length )
    {
      GXV_TRACE(( "featureType %d is out of registered range, "
                  "setting %d is unchecked\n",
                  f->featureType, f->featureSetting ));
      if ( valid->root->level >= FT_VALIDATE_PARANOID )
        FT_INVALID_DATA;
    }
    else if ( !gxv_feat_registry[f->featureType].existence )
    {
      GXV_TRACE(( "featureType %d is within registered area "
                  "but undefined, setting %d is unchecked\n",
                  f->featureType, f->featureSetting ));
      if ( valid->root->level >= FT_VALIDATE_PARANOID )
        FT_INVALID_DATA;
    }
    else
    {
      FT_Byte  nSettings_max;


      /* nSettings in gxvfeat.c is halved for exclusive on/off settings */
      nSettings_max = gxv_feat_registry[f->featureType].nSettings;
      if ( gxv_feat_registry[f->featureType].exclusive )
        nSettings_max = (FT_Byte)( 2 * nSettings_max );

      GXV_TRACE(( "featureType %d is registered", f->featureType ));
      GXV_TRACE(( "setting %d", f->featureSetting ));

      if ( f->featureSetting > nSettings_max )
      {
        GXV_TRACE(( "out of defined range %d", nSettings_max ));
        if ( valid->root->level >= FT_VALIDATE_PARANOID )
          FT_INVALID_DATA;
      }
      GXV_TRACE(( "\n" ));
    }

    /* TODO: enableFlags must be unique value in specified chain?  */
  }


  /*
   * nFeatureFlags is typed to FT_ULong to accept that in
   * mort (typed FT_UShort) and morx (typed FT_ULong).
   */
  FT_LOCAL_DEF( void )
  gxv_mort_featurearray_validate( FT_Bytes       table,
                                  FT_Bytes       limit,
                                  FT_ULong       nFeatureFlags,
                                  GXV_Validator  valid )
  {
    FT_Bytes  p = table;
    FT_ULong  i;

    GXV_mort_featureRec  f = GXV_MORT_FEATURE_OFF;


    GXV_NAME_ENTER( "mort feature list" );
    for ( i = 0; i < nFeatureFlags; i++ )
    {
      GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 );
      f.featureType    = FT_NEXT_USHORT( p );
      f.featureSetting = FT_NEXT_USHORT( p );
      f.enableFlags    = FT_NEXT_ULONG( p );
      f.disableFlags   = FT_NEXT_ULONG( p );

      gxv_mort_feature_validate( &f, valid );
    }

    if ( !IS_GXV_MORT_FEATURE_OFF( f ) )
      FT_INVALID_DATA;

    valid->subtable_length = p - table;
    GXV_EXIT;
  }


  FT_LOCAL_DEF( void )
  gxv_mort_coverage_validate( FT_UShort      coverage,
                              GXV_Validator  valid )
  {
    FT_UNUSED( valid );

    if ( coverage & 0x8000U )
      GXV_TRACE(( " this subtable is for vertical text only\n" ));
    else
      GXV_TRACE(( " this subtable is for horizontal text only\n" ));

    if ( coverage & 0x4000 )
      GXV_TRACE(( " this subtable is applied to glyph array "
                  "in descending order\n" ));
    else
      GXV_TRACE(( " this subtable is applied to glyph array "
                  "in ascending order\n" ));

    if ( coverage & 0x2000 )
      GXV_TRACE(( " this subtable is forcibly applied to "
                  "vertical/horizontal text\n" ));

    if ( coverage & 0x1FF8 )
      GXV_TRACE(( " coverage has non-zero bits in reserved area\n" ));
  }


  static void
  gxv_mort_subtables_validate( FT_Bytes       table,
                               FT_Bytes       limit,
                               FT_UShort      nSubtables,
                               GXV_Validator  valid )
  {
    FT_Bytes  p = table;

    GXV_Validate_Func fmt_funcs_table[] =
    {
      gxv_mort_subtable_type0_validate, /* 0 */
      gxv_mort_subtable_type1_validate, /* 1 */
      gxv_mort_subtable_type2_validate, /* 2 */
      NULL,                             /* 3 */
      gxv_mort_subtable_type4_validate, /* 4 */
      gxv_mort_subtable_type5_validate, /* 5 */

    };

    GXV_Validate_Func  func;
    FT_UShort          i;


    GXV_NAME_ENTER( "subtables in a chain" );

    for ( i = 0; i < nSubtables; i++ )
    {
      FT_UShort  length;
      FT_UShort  coverage;
      FT_ULong   subFeatureFlags;
      FT_UInt    type;
      FT_UInt    rest;


      GXV_LIMIT_CHECK( 2 + 2 + 4 );
      length          = FT_NEXT_USHORT( p );
      coverage        = FT_NEXT_USHORT( p );
      subFeatureFlags = FT_NEXT_ULONG( p );

      GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n",
                  i + 1, nSubtables, length ));
      type = coverage & 0x0007;
      rest = length - ( 2 + 2 + 4 );

      GXV_LIMIT_CHECK( rest );
      gxv_mort_coverage_validate( coverage, valid );

      if ( type > 5 )
        FT_INVALID_FORMAT;

      func = fmt_funcs_table[type];
      if ( func == NULL )
        GXV_TRACE(( "morx type %d is reserved\n", type ));

      func( p, p + rest, valid );

      p += rest;
    }

    valid->subtable_length = p - table;

    GXV_EXIT;
  }


  static void
  gxv_mort_chain_validate( FT_Bytes       table,
                           FT_Bytes       limit,
                           GXV_Validator  valid )
  {
    FT_Bytes   p = table;
    FT_ULong   defaultFlags;
    FT_ULong   chainLength;
    FT_UShort  nFeatureFlags;
    FT_UShort  nSubtables;


    GXV_NAME_ENTER( "mort chain header" );

    GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
    defaultFlags  = FT_NEXT_ULONG( p );
    chainLength   = FT_NEXT_ULONG( p );
    nFeatureFlags = FT_NEXT_USHORT( p );
    nSubtables    = FT_NEXT_USHORT( p );

    gxv_mort_featurearray_validate( p, table + chainLength,
                                    nFeatureFlags, valid );
    p += valid->subtable_length;
    gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid );
    valid->subtable_length = chainLength;

    GXV_EXIT;
  }


  FT_LOCAL_DEF( void )
  gxv_mort_validate( FT_Bytes      table,
                     FT_Face       face,
                     FT_Validator  ftvalid )
  {
    GXV_ValidatorRec  validrec;
    GXV_Validator     valid = &validrec;
    FT_Bytes          p     = table;
    FT_Bytes          limit = 0;
    FT_ULong          version;
    FT_ULong          nChains;
    FT_ULong          i;


    valid->root = ftvalid;
    valid->face = face;
    limit       = valid->root->limit;

    FT_TRACE3(( "validating `mort' table\n" ));
    GXV_INIT;

    GXV_LIMIT_CHECK( 4 + 4 );
    version = FT_NEXT_ULONG( p );
    nChains = FT_NEXT_ULONG( p );

    if (version != 0x00010000UL)
      FT_INVALID_FORMAT;

    for ( i = 0; i < nChains; i++ )
    {
      GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains ));
      GXV_32BIT_ALIGNMENT_VALIDATE( p - table );
      gxv_mort_chain_validate( p, limit, valid );
      p += valid->subtable_length;
    }

    FT_TRACE4(( "\n" ));
  }


/* END */

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Brazil Brazil
I live in Matão, a small city in Brazil. I studied as Programmer in a College for Software Development in Database.
After finishing the College I have been working with java, c# and Computer Graphics with searches for OpenGL.

Comments and Discussions