コード例 #1
0
ファイル: ftstroke.c プロジェクト: gbarrand/ArcheryTune
  FT_Outline_GetOutsideBorder( FT_Outline*  outline )
  {
    FT_Orientation  o = FT_Outline_Get_Orientation( outline );


    return o == FT_ORIENTATION_TRUETYPE ? FT_STROKER_BORDER_LEFT
                                        : FT_STROKER_BORDER_RIGHT ;
  }
コード例 #2
0
ファイル: outline.c プロジェクト: anthrotype/freetypy
static PyObject*
Py_Outline_get_orientation(Py_Outline* self, PyObject* args, PyObject* kwds)
{
    int orientation;

    orientation = FT_Outline_Get_Orientation(&self->x);

    return Py_Constant_cnew(&Py_FT_ORIENTATION_ConstantType, orientation);
}
コード例 #3
0
unsigned int get_contour_type(FT_Outline& outline, unsigned int c)
{
	FT_Orientation orientation = FT_Outline_Get_Orientation(&outline);
	unsigned int order = get_contour_order(outline, c);

	if      (orientation==FT_ORIENTATION_TRUETYPE   && order==kOrderCounterClockwise)
		return kContourTypeInner;
	else if (orientation==FT_ORIENTATION_TRUETYPE   && order==kOrderClockwise)
		return kContourTypeOuter;
	else if (orientation==FT_ORIENTATION_POSTSCRIPT && order==kOrderCounterClockwise)
		return kContourTypeOuter;
	else if (orientation==FT_ORIENTATION_POSTSCRIPT && order==kOrderClockwise)
		return kContourTypeInner;
	else
		return -1;
}
コード例 #4
0
ファイル: FTFontExt.cpp プロジェクト: CCQIU/CGE
// 新的加粗函数
FT_Error New_FT_Outline_Embolden( FT_Outline*  outline, FT_Pos str_h, FT_Pos str_v )
{
	int orientation;
    if ( !outline )
		return FT_Err_Invalid_Argument;

     orientation = FT_Outline_Get_Orientation( outline );

    if ( orientation == FT_ORIENTATION_NONE )
        if ( outline->n_contours )
			return FT_Err_Invalid_Argument;

    Vert_FT_Outline_Embolden( outline, str_v );
    Old_FT_Outline_Embolden( outline, str_h );

    return FT_Err_Ok;
}
コード例 #5
0
ファイル: ftoutln.c プロジェクト: ShaneIsley/challengeq3
  FT_Outline_Embolden( FT_Outline*  outline,
                       FT_Pos       strength )
  {
    FT_Vector*  points;
    FT_Vector   v_prev, v_first, v_next, v_cur;
    FT_Angle    rotate, angle_in, angle_out;
    FT_Int      c, n, first;
    FT_Int      orientation;


    if ( !outline )
      return FT_Err_Invalid_Argument;

    strength /= 2;
    if ( strength == 0 )
      return FT_Err_Ok;

    orientation = FT_Outline_Get_Orientation( outline );
    if ( orientation == FT_ORIENTATION_NONE )
    {
      if ( outline->n_contours )
        return FT_Err_Invalid_Argument;
      else
        return FT_Err_Ok;
    }

    if ( orientation == FT_ORIENTATION_TRUETYPE )
      rotate = -FT_ANGLE_PI2;
    else
      rotate = FT_ANGLE_PI2;

    points = outline->points;

    first = 0;
    for ( c = 0; c < outline->n_contours; c++ )
    {
      int  last = outline->contours[c];


      v_first = points[first];
      v_prev  = points[last];
      v_cur   = v_first;

      for ( n = first; n <= last; n++ )
      {
        FT_Vector  in, out;
        FT_Angle   angle_diff;
        FT_Pos     d;
        FT_Fixed   scale;


        if ( n < last )
          v_next = points[n + 1];
        else
          v_next = v_first;

        /* compute the in and out vectors */
        in.x = v_cur.x - v_prev.x;
        in.y = v_cur.y - v_prev.y;

        out.x = v_next.x - v_cur.x;
        out.y = v_next.y - v_cur.y;

        angle_in   = FT_Atan2( in.x, in.y );
        angle_out  = FT_Atan2( out.x, out.y );
        angle_diff = FT_Angle_Diff( angle_in, angle_out );
        scale      = FT_Cos( angle_diff / 2 );

        if ( scale < 0x4000L && scale > -0x4000L )
          in.x = in.y = 0;
        else
        {
          d = FT_DivFix( strength, scale );

          FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );
        }

        outline->points[n].x = v_cur.x + strength + in.x;
        outline->points[n].y = v_cur.y + strength + in.y;

        v_prev = v_cur;
        v_cur  = v_next;
      }

      first = last + 1;
    }

    return FT_Err_Ok;
  }
コード例 #6
0
ファイル: ftoutln.c プロジェクト: 568210356/fancy2d
  FT_Outline_EmboldenXY( FT_Outline*  outline,
                         FT_Pos       xstrength,
                         FT_Pos       ystrength )
  {
    FT_Vector*  points;
    FT_Vector   v_prev, v_first, v_next, v_cur;
    FT_Int      c, n, first;
    FT_Int      orientation;


    if ( !outline )
      return FT_Err_Invalid_Argument;

    xstrength /= 2;
    ystrength /= 2;
    if ( xstrength == 0 && ystrength == 0 )
      return FT_Err_Ok;

    orientation = FT_Outline_Get_Orientation( outline );
    if ( orientation == FT_ORIENTATION_NONE )
    {
      if ( outline->n_contours )
        return FT_Err_Invalid_Argument;
      else
        return FT_Err_Ok;
    }

    points = outline->points;

    first = 0;
    for ( c = 0; c < outline->n_contours; c++ )
    {
      FT_Vector  in, out, shift;
      FT_Fixed   l_in, l_out, l, q, d;
      int        last = outline->contours[c];


      v_first = points[first];
      v_prev  = points[last];
      v_cur   = v_first;

      /* compute the incoming vector and its length */
      in.x = v_cur.x - v_prev.x;
      in.y = v_cur.y - v_prev.y;
      l_in = FT_Vector_Length( &in );

      for ( n = first; n <= last; n++ )
      {
        if ( n < last )
          v_next = points[n + 1];
        else
          v_next = v_first;

        /* compute the outgoing vector and its length */
        out.x = v_next.x - v_cur.x;
        out.y = v_next.y - v_cur.y;
        l_out = FT_Vector_Length( &out );

        d = l_in * l_out + in.x * out.x + in.y * out.y;

        /* shift only if turn is less then ~160 degrees */
        if ( 16 * d > l_in * l_out )
        {
          /* shift components are aligned along bisector        */
          /* and directed according to the outline orientation. */
          shift.x = l_out * in.y + l_in * out.y;
          shift.y = l_out * in.x + l_in * out.x;

          if ( orientation == FT_ORIENTATION_TRUETYPE )
            shift.x = -shift.x;
          else
            shift.y = -shift.y;

          /* threshold strength to better handle collapsing segments */
          l = FT_MIN( l_in, l_out );
          q = out.x * in.y - out.y * in.x;
          if ( orientation == FT_ORIENTATION_TRUETYPE )
            q = -q;

          if ( FT_MulDiv( xstrength, q, l ) < d )
            shift.x = FT_MulDiv( shift.x, xstrength, d );
          else
            shift.x = FT_MulDiv( shift.x, l, q );

          
          if ( FT_MulDiv( ystrength, q, l ) < d )
            shift.y = FT_MulDiv( shift.y, ystrength, d );
          else
            shift.y = FT_MulDiv( shift.y, l, q );
        }
        else
          shift.x = shift.y = 0;

        outline->points[n].x = v_cur.x + xstrength + shift.x;
        outline->points[n].y = v_cur.y + ystrength + shift.y;

        in    = out;
        l_in  = l_out;
        v_cur = v_next;
      }

      first = last + 1;
    }

    return FT_Err_Ok;
  }
コード例 #7
0
static void GK_Outline_Embolden(FT_Outline* outline,FT_Pos strength,int* x_left,int* x_right,int* y_bottom,int* y_top)
{
    FT_Vector*  points;
    FT_Vector   v_prev, v_first, v_next, v_cur;
    FT_Angle    rotate, angle_in, angle_out;
    FT_Int      c, n, first = 0;
    FT_Int      orientation;
    FT_Int      min_x = 35565, max_x = -35565, min_y = 35565, max_y = -35565;
    FT_Int      new_min_x = 35565, new_max_x = -35565, new_min_y = 35565, new_max_y = -35565;

    if (!outline) return;

    strength /= 2;
    if ( strength == 0 ) return;

    orientation = FT_Outline_Get_Orientation(outline);
    if (orientation == FT_ORIENTATION_NONE) return;

#ifdef GLYPH_LOG
    if (glyph_log) { fprintf(glyph_log,"            Emboldening the outline by %ld:\n",strength); }
#endif

    if (orientation == FT_ORIENTATION_TRUETYPE) rotate = -FT_ANGLE_PI2;
    else rotate = FT_ANGLE_PI2;

    points = outline->points;

    for ( c = 0; c < outline->n_contours; c++ )
    {
        int last = outline->contours[c];

        v_first = points[first];
        v_prev  = points[last];
        v_cur   = v_first;

        for ( n = first; n <= last; n++ )
        {
            FT_Vector  in, out;
            FT_Angle   angle_diff;
            FT_Pos     d;
            FT_Fixed   scale;

            if ( n < last ) v_next = points[n + 1];
            else v_next = v_first;

            /* compute the in and out vectors */
            in.x = v_cur.x - v_prev.x;
            in.y = v_cur.y - v_prev.y;

            out.x = v_next.x - v_cur.x;
            out.y = v_next.y - v_cur.y;

            angle_in   = FT_Atan2( in.x, in.y );
            angle_out  = FT_Atan2( out.x, out.y );
            angle_diff = FT_Angle_Diff( angle_in, angle_out );
            scale      = FT_Cos( angle_diff / 2 );

            if ( scale < 0x4000L && scale > -0x4000L ) in.x = in.y = 0;
            else
            {
                d = FT_DivFix( strength, scale );
                FT_Vector_From_Polar( &in, d, angle_in + angle_diff / 2 - rotate );
            }

            outline->points[n].x = v_cur.x + strength + in.x;
            outline->points[n].y = v_cur.y + strength + in.y;

            if (v_cur.x < min_x) min_x = v_cur.x;
            if (v_cur.x > max_x) max_x = v_cur.x;
            if (v_cur.y < min_y) min_y = v_cur.y;
            if (v_cur.y > max_y) max_y = v_cur.y;

            if (outline->points[n].x < new_min_x) new_min_x = outline->points[n].x;
            if (outline->points[n].x > new_max_x) new_max_x = outline->points[n].x;
            if (outline->points[n].y < new_min_y) new_min_y = outline->points[n].y;
            if (outline->points[n].y > new_max_y) new_max_y = outline->points[n].y;

            v_prev = v_cur;
            v_cur  = v_next;
        }

        first = last + 1;
    }

    *x_left = min_x - new_min_x;
    *x_right = new_max_x - max_x;
    *y_top = new_max_y - max_y;
    *y_bottom = min_y - new_min_y;

#ifdef GLYPH_LOG
    if (glyph_log)
    {
        fprintf(glyph_log,"                (%d..%d x %d..%d) -> (%d..%d x %d..%d)\n",
                           min_x,max_x,min_y,max_y,new_min_x,new_max_x,new_min_y,new_max_y);
    }
#endif
}
コード例 #8
0
ファイル: afhints.c プロジェクト: zdementor/my-deps
af_glyph_hints_reload( AF_GlyphHints     hints,
                       FT_Outline*       outline )
{
    FT_Error     error        = FT_Err_Ok;
    AF_Point     points;
    FT_UInt      old_max, new_max;
    AF_Scaler    scaler  = &hints->metrics->scaler;
    FT_Fixed     x_scale = hints->x_scale;
    FT_Fixed     y_scale = hints->y_scale;
    FT_Pos       x_delta = hints->x_delta;
    FT_Pos       y_delta = hints->y_delta;
    FT_Memory    memory  = hints->memory;

    hints->scaler_flags  = scaler->flags;
    hints->num_points    = 0;
    hints->num_contours  = 0;

    hints->axis[0].num_segments = 0;
    hints->axis[0].num_edges    = 0;
    hints->axis[1].num_segments = 0;
    hints->axis[1].num_edges    = 0;

    /* first of all, reallocate the contours array when necessary
     */
    new_max = (FT_UInt) outline->n_contours;
    old_max = hints->max_contours;
    if ( new_max > old_max )
    {
        new_max = (new_max + 3) & ~3;

        if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )
            goto Exit;

        hints->max_contours = new_max;
    }

    /* then, reallocate the points, segments & edges arrays if needed --
     * note that we reserved two additional point positions, used to
     * hint metrics appropriately
     */
    new_max = (FT_UInt)( outline->n_points + 2 );
    old_max = hints->max_points;
    if ( new_max > old_max )
    {
        FT_Byte*    items;
        FT_ULong    off1, off2, off3;

        /* we store in a single buffer the following arrays:
         *
         *  - an array of   N  AF_PointRec   items
         *  - an array of 2*N  AF_SegmentRec items
         *  - an array of 2*N  AF_EdgeRec    items
         *
         */

        new_max = ( new_max + 2 + 7 ) & ~7;

#define OFF_PAD2(x,y)   (((x)+(y)-1) & ~((y)-1))
#define OFF_PADX(x,y)   ((((x)+(y)-1)/(y))*(y))
#define OFF_PAD(x,y)    ( ((y) & ((y)-1)) ? OFF_PADX(x,y) : OFF_PAD2(x,y) )

#undef  OFF_INCREMENT
#define OFF_INCREMENT( _off, _type, _count )   \
     ( OFF_PAD( _off, sizeof(_type) ) + (_count)*sizeof(_type))

        off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );
        off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max*2 );
        off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );

        FT_FREE( hints->points );

        if ( FT_ALLOC( items, off3 ) )
        {
            hints->max_points       = 0;
            hints->axis[0].segments = NULL;
            hints->axis[0].edges    = NULL;
            hints->axis[1].segments = NULL;
            hints->axis[1].edges    = NULL;
            goto Exit;
        }

        /* readjust some pointers
         */
        hints->max_points       = new_max;
        hints->points           = (AF_Point) items;

        hints->axis[0].segments = (AF_Segment)( items + off1 );
        hints->axis[1].segments = hints->axis[0].segments + new_max;

        hints->axis[0].edges    = (AF_Edge)   ( items + off2 );
        hints->axis[1].edges    = hints->axis[0].edges + new_max;
    }

    hints->num_points   = outline->n_points;
    hints->num_contours = outline->n_contours;


    /* We can't rely on the value of `FT_Outline.flags' to know the fill  */
    /* direction used for a glyph, given that some fonts are broken (e.g. */
    /* the Arphic ones).  We thus recompute it each time we need to.      */
    /*                                                                    */
    hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;
    hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;

    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )
    {
        hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;
        hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;
    }

    hints->x_scale = x_scale;
    hints->y_scale = y_scale;
    hints->x_delta = x_delta;
    hints->y_delta = y_delta;

    points = hints->points;
    if ( hints->num_points == 0 )
        goto Exit;

    {
        AF_Point  point;
        AF_Point  point_limit = points + hints->num_points;


        /* compute coordinates & bezier flags */
        {
            FT_Vector*  vec = outline->points;
            char*       tag = outline->tags;


            for ( point = points; point < point_limit; point++, vec++, tag++ )
            {
                point->fx = vec->x;
                point->fy = vec->y;
                point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;
                point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;

                switch ( FT_CURVE_TAG( *tag ) )
                {
                case FT_CURVE_TAG_CONIC:
                    point->flags = AF_FLAG_CONIC;
                    break;
                case FT_CURVE_TAG_CUBIC:
                    point->flags = AF_FLAG_CUBIC;
                    break;
                default:
                    point->flags = 0;
                    ;
                }
            }
        }

        /* compute `next' and `prev' */
        {
            FT_Int    contour_index;
            AF_Point  prev;
            AF_Point  first;
            AF_Point  end;


            contour_index = 0;

            first = points;
            end   = points + outline->contours[0];
            prev  = end;

            for ( point = points; point < point_limit; point++ )
            {
                point->prev = prev;
                if ( point < end )
                {
                    point->next = point + 1;
                    prev        = point;
                }
                else
                {
                    point->next = first;
                    contour_index++;
                    if ( point + 1 < point_limit )
                    {
                        end   = points + outline->contours[contour_index];
                        first = point + 1;
                        prev  = end;
                    }
                }
            }
        }

        /* set-up the contours array */
        {
            AF_Point*  contour       = hints->contours;
            AF_Point*  contour_limit = contour + hints->num_contours;
            short*     end           = outline->contours;
            short      idx           = 0;


            for ( ; contour < contour_limit; contour++, end++ )
            {
                contour[0] = points + idx;
                idx        = (short)( end[0] + 1 );
            }
        }

        /* compute directions of in & out vectors */
        {
            for ( point = points; point < point_limit; point++ )
            {
                AF_Point   prev;
                AF_Point   next;
                FT_Pos     in_x, in_y, out_x, out_y;


                prev   = point->prev;
                in_x   = point->fx - prev->fx;
                in_y   = point->fy - prev->fy;

                point->in_dir = af_direction_compute( in_x, in_y );

                next   = point->next;
                out_x  = next->fx - point->fx;
                out_y  = next->fy - point->fy;

                point->out_dir = af_direction_compute( out_x, out_y );

                if ( point->flags & ( AF_FLAG_CONIC | AF_FLAG_CUBIC ) )
                {
Is_Weak_Point:
                    point->flags |= AF_FLAG_WEAK_INTERPOLATION;
                }
                else if ( point->out_dir == point->in_dir )
                {
                    AF_Angle  angle_in, angle_out, delta;


                    if ( point->out_dir != AF_DIR_NONE )
                        goto Is_Weak_Point;

                    angle_in  = af_angle_atan( in_x, in_y );
                    angle_out = af_angle_atan( out_x, out_y );
                    delta     = af_angle_diff( angle_in, angle_out );

                    if ( delta < 2 && delta > -2 )
                        goto Is_Weak_Point;
                }
                else if ( point->in_dir == -point->out_dir )
                    goto Is_Weak_Point;
            }
        }
    }

    /* compute inflection points
     */
    af_glyph_hints_compute_inflections( hints );

Exit:
    return error;
}
コード例 #9
0
ファイル: ftoutln.c プロジェクト: CCExtractor/ccextractor
  FT_Outline_EmboldenXY( FT_Outline*  outline,
                         FT_Pos       xstrength,
                         FT_Pos       ystrength )
  {
    FT_Vector*  points;
    FT_Int      c, first, last;
    FT_Int      orientation;


    if ( !outline )
      return FT_THROW( Invalid_Outline );

    xstrength /= 2;
    ystrength /= 2;
    if ( xstrength == 0 && ystrength == 0 )
      return FT_Err_Ok;

    orientation = FT_Outline_Get_Orientation( outline );
    if ( orientation == FT_ORIENTATION_NONE )
    {
      if ( outline->n_contours )
        return FT_THROW( Invalid_Argument );
      else
        return FT_Err_Ok;
    }

    points = outline->points;

    first = 0;
    for ( c = 0; c < outline->n_contours; c++ )
    {
      FT_Vector  in, out, anchor, shift;
      FT_Fixed   l_in, l_out, l_anchor = 0, l, q, d;
      FT_Int     i, j, k;


      l_in = 0;
      last = outline->contours[c];

      /* pacify compiler */
      in.x = in.y = anchor.x = anchor.y = 0;

      /* Counter j cycles though the points; counter i advances only  */
      /* when points are moved; anchor k marks the first moved point. */
      for ( i = last, j = first, k = -1;
            j != i && i != k;
            j = j < last ? j + 1 : first )
      {
        if ( j != k )
        {
          out.x = points[j].x - points[i].x;
          out.y = points[j].y - points[i].y;
          l_out = (FT_Fixed)FT_Vector_NormLen( &out );

          if ( l_out == 0 )
            continue;
        }
        else
        {
          out   = anchor;
          l_out = l_anchor;
        }

        if ( l_in != 0 )
        {
          if ( k < 0 )
          {
            k        = i;
            anchor   = in;
            l_anchor = l_in;
          }

          d = FT_MulFix( in.x, out.x ) + FT_MulFix( in.y, out.y );

          /* shift only if turn is less than ~160 degrees */
          if ( d > -0xF000L )
          {
            d = d + 0x10000L;

            /* shift components along lateral bisector in proper orientation */
            shift.x = in.y + out.y;
            shift.y = in.x + out.x;

            if ( orientation == FT_ORIENTATION_TRUETYPE )
              shift.x = -shift.x;
            else
              shift.y = -shift.y;

            /* restrict shift magnitude to better handle collapsing segments */
            q = FT_MulFix( out.x, in.y ) - FT_MulFix( out.y, in.x );
            if ( orientation == FT_ORIENTATION_TRUETYPE )
              q = -q;

            l = FT_MIN( l_in, l_out );

            /* non-strict inequalities avoid divide-by-zero when q == l == 0 */
            if ( FT_MulFix( xstrength, q ) <= FT_MulFix( l, d ) )
              shift.x = FT_MulDiv( shift.x, xstrength, d );
            else
              shift.x = FT_MulDiv( shift.x, l, q );


            if ( FT_MulFix( ystrength, q ) <= FT_MulFix( l, d ) )
              shift.y = FT_MulDiv( shift.y, ystrength, d );
            else
              shift.y = FT_MulDiv( shift.y, l, q );
          }
          else
            shift.x = shift.y = 0;

          for ( ;
                i != j;
                i = i < last ? i + 1 : first )
          {
            points[i].x += xstrength + shift.x;
            points[i].y += ystrength + shift.y;
          }
        }
        else
          i = j;

        in   = out;
        l_in = l_out;
      }

      first = last + 1;
    }

    return FT_Err_Ok;
  }
コード例 #10
0
osgText::Glyph3D * FreeTypeFont::getGlyph3D(const osgText::FontResolution& fontRes, unsigned int charcode)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(FreeTypeLibrary::instance()->getMutex());

    setFontResolution(fontRes);

    //
    // GT: fix for symbol fonts (i.e. the Webdings font) as the wrong character are being
    // returned, for symbol fonts in windows (FT_ENCONDING_MS_SYMBOL in freetype) the correct
    // values are from 0xF000 to 0xF0FF not from 0x000 to 0x00FF (0 to 255) as you would expect.
    // Microsoft uses a private field for its symbol fonts
    //
    unsigned int charindex = charcode;
    if (_face->charmap != NULL)
    {
        if (_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
        {
            charindex |= 0xF000;
        }
    }

    FT_Error error = FT_Load_Char( _face, charindex, FT_LOAD_DEFAULT|_flags );
    if (error)
    {
        OSG_WARN << "FT_Load_Char(...) error 0x"<<std::hex<<error<<std::dec<<std::endl;
        return 0;
    }
    if (_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)
    {
        OSG_WARN << "FreeTypeFont3D::getGlyph : not a vector font" << std::endl;
        return 0;
    }

    float coord_scale = getCoordScale();

    // ** init FreeType to describe the glyph
    FreeType::Char3DInfo char3d(_facade->getNumberCurveSamples());
    char3d._coord_scale = coord_scale;

    FT_Outline outline = _face->glyph->outline;
    FT_Outline_Funcs funcs;
    funcs.conic_to = (FT_Outline_ConicToFunc)&FreeType::conicTo;
    funcs.line_to = (FT_Outline_LineToFunc)&FreeType::lineTo;
    funcs.cubic_to = (FT_Outline_CubicToFunc)&FreeType::cubicTo;
    funcs.move_to = (FT_Outline_MoveToFunc)&FreeType::moveTo;
    funcs.shift = 0;
    funcs.delta = 0;

    FT_Orientation orientation = FT_Outline_Get_Orientation(&outline);
    char3d._reverseFill = (orientation == FT_ORIENTATION_POSTSCRIPT);

    // ** record description
    FT_Error _error = FT_Outline_Decompose(&outline, &funcs, &char3d);
    if (_error)
    {
        OSG_WARN << "FreeTypeFont3D::getGlyph : - outline decompose failed ..." << std::endl;
        return 0;
    }

    // ** create geometry for each part of the glyph
    osg::ref_ptr<osg::Geometry> frontGeo(new osg::Geometry);

    osg::ref_ptr<osg::Vec3Array> rawVertices = new osg::Vec3Array(*(char3d._verts));
    osg::Geometry::PrimitiveSetList rawPrimitives;
    for(osg::Geometry::PrimitiveSetList::iterator itr = char3d.get()->getPrimitiveSetList().begin();
        itr != char3d.get()->getPrimitiveSetList().end();
        ++itr)
    {
        rawPrimitives.push_back(dynamic_cast<osg::PrimitiveSet*>((*itr)->clone(osg::CopyOp::DEEP_COPY_ALL)));
    }

    // ** save vertices and PrimitiveSetList of each face in the Glyph3D PrimitiveSet face list
    osg::ref_ptr<osgText::Glyph3D> glyph = new osgText::Glyph3D(_facade, charcode);

    // copy the raw primitive set list before we tessellate it.
    glyph->getRawFacePrimitiveSetList() = rawPrimitives;
    glyph->setRawVertexArray(rawVertices.get());


    FT_Glyph_Metrics* metrics = &(_face->glyph->metrics);

    glyph->setWidth((float)metrics->width * coord_scale);
    glyph->setHeight((float)metrics->height * coord_scale);
    glyph->setHorizontalBearing(osg::Vec2((float)metrics->horiBearingX * coord_scale,(float)(metrics->horiBearingY-metrics->height) * coord_scale)); // bottom left.
    glyph->setHorizontalAdvance((float)metrics->horiAdvance * coord_scale);
    glyph->setVerticalBearing(osg::Vec2((float)metrics->vertBearingX * coord_scale,(float)(metrics->vertBearingY-metrics->height) * coord_scale)); // top middle.
    glyph->setVerticalAdvance((float)metrics->vertAdvance * coord_scale);

#if 0
    OSG_NOTICE<<"getGlyph3D("<<charcode<<", "<<char(charcode)<<")"<<std::endl;
    OSG_NOTICE<<"   height="<<glyph->getHeight()<<std::endl;
    OSG_NOTICE<<"   width="<<glyph->getWidth()<<std::endl;
    OSG_NOTICE<<"   horizontalBearing="<<glyph->getHorizontalBearing()<<std::endl;
    OSG_NOTICE<<"   horizontalAdvance="<<glyph->getHorizontalAdvance()<<std::endl;
    OSG_NOTICE<<"   verticalBearing="<<glyph->getHorizontalBearing()<<std::endl;
    OSG_NOTICE<<"   verticalAdvance="<<glyph->getVerticalAdvance()<<std::endl;
#endif

    FT_BBox ftbb;
    FT_Outline_Get_BBox(&outline, &ftbb);
    osg::BoundingBox bb(float(ftbb.xMin) * coord_scale, float(ftbb.yMin) * coord_scale, 0.0f, float(ftbb.xMax) * coord_scale, float(ftbb.yMax) * coord_scale, 0.0f);

    glyph->setBoundingBox(bb);

    return glyph.release();
}
コード例 #11
0
ファイル: ftoutln.c プロジェクト: 2007750219/softart
  FT_Outline_EmboldenXY( FT_Outline*  outline,
                         FT_Pos       xstrength,
                         FT_Pos       ystrength )
  {
    FT_Vector*  points;
    FT_Vector   v_prev, v_first, v_next, v_cur;
    FT_Int      c, n, first;
    FT_Int      orientation;


    if ( !outline )
      return FT_Err_Invalid_Argument;

    xstrength /= 2;
    ystrength /= 2;
    if ( xstrength == 0 && ystrength == 0 )
      return FT_Err_Ok;

    orientation = FT_Outline_Get_Orientation( outline );
    if ( orientation == FT_ORIENTATION_NONE )
    {
      if ( outline->n_contours )
        return FT_Err_Invalid_Argument;
      else
        return FT_Err_Ok;
    }

    points = outline->points;

    first = 0;
    for ( c = 0; c < outline->n_contours; c++ )
    {
      FT_Vector  in, out, shift;
      FT_Fixed   l_in, l_out, d;
      int        last = outline->contours[c];


      v_first = points[first];
      v_prev  = points[last];
      v_cur   = v_first;

      /* compute the incoming vector and its length */
      in.x = v_cur.x - v_prev.x;
      in.y = v_cur.y - v_prev.y;
      l_in = FT_Vector_Length( &in );

      for ( n = first; n <= last; n++ )
      {
        if ( n < last )
          v_next = points[n + 1];
        else
          v_next = v_first;

        /* compute the outgoing vector and its length */
        out.x = v_next.x - v_cur.x;
        out.y = v_next.y - v_cur.y;
        l_out = FT_Vector_Length( &out );

        d = l_in * l_out + in.x * out.x + in.y * out.y;

        /* shift only if turn is less then ~160 degrees */
        if ( 16 * d > l_in * l_out )
        {
          /* shift components are rotated */
          shift.x = FT_DivFix( l_out * in.y + l_in * out.y, d );
          shift.y = FT_DivFix( l_out * in.x + l_in * out.x, d );

          if ( orientation == FT_ORIENTATION_TRUETYPE )
            shift.x = -shift.x;
          else
            shift.y = -shift.y;

          shift.x = FT_MulFix( xstrength, shift.x );
          shift.y = FT_MulFix( ystrength, shift.y );
        }
        else
          shift.x = shift.y = 0;

        outline->points[n].x = v_cur.x + xstrength + shift.x;
        outline->points[n].y = v_cur.y + ystrength + shift.y;

        in    = out;
        l_in  = l_out;
        v_cur = v_next;
      }

      first = last + 1;
    }

    return FT_Err_Ok;
  }