Example #1
0
  static FT_Bool
  ft_cubic_is_small_enough( FT_Vector*  base,
                            FT_Angle   *angle_in,
                            FT_Angle   *angle_mid,
                            FT_Angle   *angle_out )
  {
    FT_Vector  d1, d2, d3;
    FT_Angle   theta1, theta2;
    FT_Int     close1, close2, close3;


    d1.x = base[2].x - base[3].x;
    d1.y = base[2].y - base[3].y;
    d2.x = base[1].x - base[2].x;
    d2.y = base[1].y - base[2].y;
    d3.x = base[0].x - base[1].x;
    d3.y = base[0].y - base[1].y;

    close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y );
    close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y );
    close3 = FT_IS_SMALL( d3.x ) && FT_IS_SMALL( d3.y );

    if ( close1 || close3 )
    {
      if ( close2 )
      {
        /* basically a point */
        *angle_in = *angle_out = *angle_mid = 0;
      }
      else if ( close1 )
      {
        *angle_in  = *angle_mid = FT_Atan2( d2.x, d2.y );
        *angle_out = FT_Atan2( d3.x, d3.y );
      }
      else  /* close2 */
      {
        *angle_in  = FT_Atan2( d1.x, d1.y );
        *angle_mid = *angle_out = FT_Atan2( d2.x, d2.y );
      }
    }
    else if ( close2 )
    {
      *angle_in  = *angle_mid = FT_Atan2( d1.x, d1.y );
      *angle_out = FT_Atan2( d3.x, d3.y );
    }
    else
    {
      *angle_in  = FT_Atan2( d1.x, d1.y );
      *angle_mid = FT_Atan2( d2.x, d2.y );
      *angle_out = FT_Atan2( d3.x, d3.y );
    }

    theta1 = ft_pos_abs( FT_Angle_Diff( *angle_in,  *angle_mid ) );
    theta2 = ft_pos_abs( FT_Angle_Diff( *angle_mid, *angle_out ) );

    return FT_BOOL( theta1 < FT_SMALL_CUBIC_THRESHOLD &&
                    theta2 < FT_SMALL_CUBIC_THRESHOLD );
  }
Example #2
0
  static FT_Orientation
  ft_orientation_extremum_compute( FT_OrientationExtremumRec*  extremum,
                                   FT_Outline*                 outline )
  {
    FT_Vector  *point, *first, *last, *prev, *next;
    FT_Vector*  points = outline->points;
    FT_Angle    angle_in, angle_out;


    /* compute the previous and next points in the same contour */
    point = points + extremum->index;
    first = points + extremum->first;
    last  = points + extremum->last;

    prev = point;
    next = point;

    do
    {
      prev = ( prev == first ) ? last : prev - 1;
      if ( prev == point )
        return FT_ORIENTATION_TRUETYPE;  /* degenerate case */

    } while ( prev->x != point->x || prev->y != point->y );

    do
    {
      next = ( next == last ) ? first : next + 1;
      if ( next == point )
        return FT_ORIENTATION_TRUETYPE;  /* shouldn't happen */

    } while ( next->x != point->x || next->y != point->y );

    /* now compute the orientation of the `out' vector relative */
    /* to the `in' vector.                                      */
    angle_in  = FT_Atan2( point->x - prev->x,  point->y - prev->y );
    angle_out = FT_Atan2( next->x  - point->x, next->y  - point->y );

    return ( FT_Angle_Diff( angle_in, angle_out ) >= 0 )
             ? FT_ORIENTATION_TRUETYPE
             : FT_ORIENTATION_POSTSCRIPT;
  }
Example #3
0
  static FT_Bool
  ft_conic_is_small_enough( FT_Vector*  base,
                            FT_Angle   *angle_in,
                            FT_Angle   *angle_out )
  {
    FT_Vector  d1, d2;
    FT_Angle   theta;
    FT_Int     close1, close2;


    d1.x = base[1].x - base[2].x;
    d1.y = base[1].y - base[2].y;
    d2.x = base[0].x - base[1].x;
    d2.y = base[0].y - base[1].y;

    close1 = FT_IS_SMALL( d1.x ) && FT_IS_SMALL( d1.y );
    close2 = FT_IS_SMALL( d2.x ) && FT_IS_SMALL( d2.y );

    if ( close1 )
    {
      if ( close2 )
        *angle_in = *angle_out = 0;
      else
        *angle_in = *angle_out = FT_Atan2( d2.x, d2.y );
    }
    else if ( close2 )
    {
      *angle_in = *angle_out = FT_Atan2( d1.x, d1.y );
    }
    else
    {
      *angle_in  = FT_Atan2( d1.x, d1.y );
      *angle_out = FT_Atan2( d2.x, d2.y );
    }

    theta = ft_pos_abs( FT_Angle_Diff( *angle_in, *angle_out ) );

    return FT_BOOL( theta < FT_SMALL_CONIC_THRESHOLD );
  }
Example #4
0
  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;
  }
Example #5
0
  /* necessary for some buggy CJK fonts.                   */
  static FT_Orientation
  ft_outline_get_orientation( FT_Outline*  outline )
  {
    FT_Short        i;
    FT_Vector*      first;
    FT_Vector*      last;
    FT_Orientation  orient = FT_ORIENTATION_NONE;


    first = outline->points;
    for ( i = 0; i < outline->n_contours; i++, first = last + 1 )
    {
      FT_Vector*  point;
      FT_Vector*  xmin_point;
      FT_Pos      xmin;


      last = outline->points + outline->contours[i];

      /* skip degenerate contours */
      if ( last < first + 2 )
        continue;

      if ( ft_contour_enclosed( outline, i ) )
        continue;

      xmin       = first->x;
      xmin_point = first;

      for ( point = first + 1; point <= last; point++ )
      {
        if ( point->x < xmin )
        {
          xmin       = point->x;
          xmin_point = point;
        }
      }

      /* check the orientation of the contour */
      {
        FT_Vector*      prev;
        FT_Vector*      next;
        FT_Orientation  o;


        prev = ( xmin_point == first ) ? last : xmin_point - 1;
        next = ( xmin_point == last ) ? first : xmin_point + 1;

        if ( FT_Atan2( prev->x - xmin_point->x, prev->y - xmin_point->y ) >
             FT_Atan2( next->x - xmin_point->x, next->y - xmin_point->y ) )
          o = FT_ORIENTATION_POSTSCRIPT;
        else
          o = FT_ORIENTATION_TRUETYPE;

        if ( orient == FT_ORIENTATION_NONE )
          orient = o;
        else if ( orient != o )
          return FT_ORIENTATION_NONE;
      }
    }

    return orient;
  }
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
}