コード例 #1
0
ファイル: tabytecode.c プロジェクト: MechanisM/entypo
static FT_Byte*
TA_sfnt_emit_hints_records(SFNT* sfnt,
                           Hints_Record* hints_records,
                           FT_UInt num_hints_records,
                           FT_Byte* bufp)
{
  FT_UInt i;
  Hints_Record* hints_record;


  hints_record = hints_records;

  for (i = 0; i < num_hints_records - 1; i++)
  {
    BCI(MPPEM);
    if (hints_record->size > 0xFF)
    {
      BCI(PUSHW_1);
      BCI(HIGH((hints_record + 1)->size));
      BCI(LOW((hints_record + 1)->size));
    }
    else
    {
      BCI(PUSHB_1);
      BCI((hints_record + 1)->size);
    }
    BCI(LT);
    BCI(IF);
    bufp = TA_sfnt_emit_hints_record(sfnt, hints_record, bufp);
    BCI(ELSE);

    hints_record++;
  }

  bufp = TA_sfnt_emit_hints_record(sfnt, hints_record, bufp);

  for (i = 0; i < num_hints_records - 1; i++)
    BCI(EIF);

  BCI(PUSHB_1);
  BCI(bci_hint_glyph);
  BCI(CALL);

  return bufp;
}
コード例 #2
0
ファイル: tabytecode.c プロジェクト: MechanisM/entypo
static FT_Byte*
TA_sfnt_build_glyph_segments(SFNT* sfnt,
                             Recorder* recorder,
                             FT_Byte* bufp)
{
  FONT* font = recorder->font;
  TA_GlyphHints hints = &font->loader->hints;
  TA_AxisHints axis = &hints->axis[TA_DIMENSION_VERT];
  TA_Point points = hints->points;
  TA_Segment segments = axis->segments;
  TA_Segment seg;
  TA_Segment seg_limit;

  FT_Outline outline = font->loader->gloader->base.outline;

  FT_UInt* args;
  FT_UInt* arg;
  FT_UInt num_args;
  FT_UInt nargs;
  FT_UInt num_segments;

  FT_UInt* wrap_around_segment;
  FT_UInt num_wrap_around_segments;

  FT_Bool need_words = 0;

  FT_Int n;
  FT_UInt i, j;
  FT_UInt base;
  FT_UInt num_packed_segments;
  FT_UInt num_storage;
  FT_UInt num_stack_elements;
  FT_UInt num_twilight_points;


  seg_limit = segments + axis->num_segments;
  num_segments = axis->num_segments;

  /* to pack the data in the bytecode more tightly, */
  /* we store up to the first nine segments in nibbles if possible, */
  /* using delta values */
  base = 0;
  num_packed_segments = 0;
  for (seg = segments; seg < seg_limit; seg++)
  {
    FT_UInt first = seg->first - points;
    FT_UInt last = seg->last - points;


    first = TA_adjust_point_index(recorder, first);
    last = TA_adjust_point_index(recorder, last);

    if (first - base >= 16)
      break;
    if (first > last || last - first >= 16)
      break;
    if (num_packed_segments == 9)
      break;
    num_packed_segments++;
    base = last;
  }

  /* some segments can `wrap around' */
  /* a contour's start point like 24-25-26-0-1-2 */
  /* (there can be at most one such segment per contour); */
  /* we thus append additional records to split them into 24-26 and 0-2 */
  wrap_around_segment = recorder->wrap_around_segments;
  /* `num_packed_segments' segments */
  /* have already been checked in previous loop */
  for (seg = segments + num_packed_segments; seg < seg_limit; seg++)
    if (seg->first > seg->last)
    {
      /* the stored data is used later for edge linking */
      *(wrap_around_segment++) = seg - segments;
    }

  num_wrap_around_segments = wrap_around_segment
                             - recorder->wrap_around_segments;
  num_segments += num_wrap_around_segments;

  /* wrap-around segments are pushed with four arguments; */
  /* a segment stored in nibbles needs only one byte instead of two */
  num_args = num_packed_segments
             + 2 * (num_segments - num_packed_segments)
             + 2 * num_wrap_around_segments
             + 2;

  /* collect all arguments temporarily in an array (in reverse order) */
  /* so that we can easily split into chunks of 255 args */
  /* as needed by NPUSHB and NPUSHW, respectively */
  args = (FT_UInt*)malloc(num_args * sizeof (FT_UInt));
  if (!args)
    return NULL;

  arg = args + num_args - 1;

  if (num_segments > 0xFF)
    need_words = 1;

  /* the number of packed segments is indicated by the function number */
  if (recorder->glyph->num_components)
    *(arg--) = bci_create_segments_composite_0 + num_packed_segments;
  else
    *(arg--) = bci_create_segments_0 + num_packed_segments;
  *(arg--) = num_segments;

  base = 0;
  for (seg = segments; seg < segments + num_packed_segments; seg++)
  {
    FT_UInt first = seg->first - points;
    FT_UInt last = seg->last - points;
    FT_UInt low_nibble;
    FT_UInt high_nibble;


    first = TA_adjust_point_index(recorder, first);
    last = TA_adjust_point_index(recorder, last);

    low_nibble = first - base;
    high_nibble = last - first;

    *(arg--) = 16 * high_nibble + low_nibble;

    base = last;

    if (last > 0xFF)
      need_words = 1;
  }

  for (seg = segments + num_packed_segments; seg < seg_limit; seg++)
  {
    FT_UInt first = seg->first - points;
    FT_UInt last = seg->last - points;


    *(arg--) = TA_adjust_point_index(recorder, first);
    *(arg--) = TA_adjust_point_index(recorder, last);

    /* we push the last and first contour point */
    /* as a third and fourth argument in wrap-around segments */
    if (first > last)
    {
      for (n = 0; n < outline.n_contours; n++)
      {
        FT_UInt end = (FT_UInt)outline.contours[n];


        if (first <= end)
        {
          *(arg--) = TA_adjust_point_index(recorder, end);
          if (end > 0xFF)
            need_words = 1;

          if (n == 0)
            *(arg--) = TA_adjust_point_index(recorder, 0);
          else
            *(arg--) = TA_adjust_point_index(recorder,
                         (FT_UInt)outline.contours[n - 1] + 1);
          break;
        }
      }
    }

    if (last > 0xFF)
      need_words = 1;
  }

  /* emit the second part of wrap-around segments as separate segments */
  /* so that edges can easily link to them */
  for (seg = segments; seg < seg_limit; seg++)
  {
    FT_UInt first = seg->first - points;
    FT_UInt last = seg->last - points;


    if (first > last)
    {
      for (n = 0; n < outline.n_contours; n++)
      {
        if (first <= (FT_UInt)outline.contours[n])
        {
          if (n == 0)
            *(arg--) = TA_adjust_point_index(recorder, 0);
          else
            *(arg--) = TA_adjust_point_index(recorder,
                         (FT_UInt)outline.contours[n - 1] + 1);
          break;
        }
      }

      *(arg--) = TA_adjust_point_index(recorder, last);
    }
  }
  /* with most fonts it is very rare */
  /* that any of the pushed arguments is larger than 0xFF, */
  /* thus we refrain from further optimizing this case */

  arg = args;

  if (need_words)
  {
    for (i = 0; i < num_args; i += 255)
    {
      nargs = (num_args - i > 255) ? 255 : num_args - i;

      BCI(NPUSHW);
      BCI(nargs);
      for (j = 0; j < nargs; j++)
      {
        BCI(HIGH(*arg));
        BCI(LOW(*arg));
        arg++;
      }
    }
  }
  else
  {
    for (i = 0; i < num_args; i += 255)
    {
      nargs = (num_args - i > 255) ? 255 : num_args - i;

      BCI(NPUSHB);
      BCI(nargs);
      for (j = 0; j < nargs; j++)
      {
        BCI(*arg);
        arg++;
      }
    }
  }

  BCI(CALL);

  num_storage = sal_segment_offset + num_segments * 2;
  if (num_storage > sfnt->max_storage)
    sfnt->max_storage = num_storage;

  num_twilight_points = num_segments * 2;
  if (num_twilight_points > sfnt->max_twilight_points)
    sfnt->max_twilight_points = num_twilight_points;

  num_stack_elements = ADDITIONAL_STACK_ELEMENTS + num_args;
  if (num_stack_elements > sfnt->max_stack_elements)
    sfnt->max_stack_elements = num_stack_elements;

  free(args);

  return bufp;
}
コード例 #3
0
ファイル: tabytecode.c プロジェクト: MechanisM/entypo
static FT_Byte*
TA_sfnt_emit_hints_record(SFNT* sfnt,
                          Hints_Record* hints_record,
                          FT_Byte* bufp)
{
  FT_Byte* p;
  FT_Byte* endp;
  FT_Bool need_words = 0;

  FT_UInt i, j;
  FT_UInt num_arguments;
  FT_UInt num_args;
  FT_UInt num_stack_elements;


  /* check whether any argument is larger than 0xFF */
  endp = hints_record->buf + hints_record->buf_len;
  for (p = hints_record->buf; p < endp; p += 2)
    if (*p)
      need_words = 1;

  /* with most fonts it is very rare */
  /* that any of the pushed arguments is larger than 0xFF, */
  /* thus we refrain from further optimizing this case */

  num_arguments = hints_record->buf_len / 2;
  p = endp - 2;

  if (need_words)
  {
    for (i = 0; i < num_arguments; i += 255)
    {
      num_args = (num_arguments - i > 255) ? 255 : (num_arguments - i);

      BCI(NPUSHW);
      BCI(num_args);
      for (j = 0; j < num_args; j++)
      {
        BCI(*p);
        BCI(*(p + 1));
        p -= 2;
      }
    }
  }
  else
  {
    /* we only need the lower bytes */
    p++;

    for (i = 0; i < num_arguments; i += 255)
    {
      num_args = (num_arguments - i > 255) ? 255 : (num_arguments - i);

      BCI(NPUSHB);
      BCI(num_args);
      for (j = 0; j < num_args; j++)
      {
        BCI(*p);
        p -= 2;
      }
    }
  }

  num_stack_elements = ADDITIONAL_STACK_ELEMENTS + num_arguments;
  if (num_stack_elements > sfnt->max_stack_elements)
    sfnt->max_stack_elements = num_stack_elements;

  return bufp;
}
コード例 #4
0
ファイル: tabytecode.c プロジェクト: MechanisM/entypo
static FT_Byte*
TA_font_build_subglyph_shifter(FONT* font,
                               FT_Byte* bufp)
{
  FT_Face face = font->loader->face;
  FT_GlyphSlot glyph = face->glyph;

  TA_GlyphLoader gloader = font->loader->gloader;

  TA_SubGlyph subglyphs = gloader->base.subglyphs;
  TA_SubGlyph subglyph_limit = subglyphs + gloader->base.num_subglyphs;
  TA_SubGlyph subglyph;

  FT_Int curr_contour = 0;


  for (subglyph = subglyphs; subglyph < subglyph_limit; subglyph++)
  {
    FT_Error error;

    FT_UShort flags = subglyph->flags;
    FT_Pos y_offset = subglyph->arg2;

    FT_Int num_contours;


    /* load subglyph to get the number of contours */
    error = FT_Load_Glyph(face, subglyph->index, FT_LOAD_NO_SCALE);
    if (error)
      return NULL;
    num_contours = glyph->outline.n_contours;

    /* nothing to do if there is a point-to-point alignment */
    if (!(flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES))
      goto End;

    /* nothing to do if y offset is zero */
    if (!y_offset)
      goto End;

    /* nothing to do if there are no contours */
    if (!num_contours)
      goto End;

    /* note that calling `FT_Load_Glyph' without FT_LOAD_NO_RECURSE */
    /* ensures that composite subglyphs are represented as simple glyphs */

    if (num_contours > 0xFF
        || curr_contour > 0xFF)
    {
      BCI(PUSHW_2);
      BCI(HIGH(curr_contour));
      BCI(LOW(curr_contour));
      BCI(HIGH(num_contours));
      BCI(LOW(num_contours));
    }
    else
    {
      BCI(PUSHB_2);
      BCI(curr_contour);
      BCI(num_contours);
    }

    /* there are high chances that this value needs PUSHW, */
    /* thus we handle it separately */
    if (y_offset > 0xFF || y_offset < 0)
    {
      BCI(PUSHW_1);
      BCI(HIGH(y_offset));
      BCI(LOW(y_offset));
    }
    else
    {
      BCI(PUSHB_1);
      BCI(y_offset);
    }

    BCI(PUSHB_1);
    BCI(bci_shift_subglyph);
    BCI(CALL);

  End:
    curr_contour += num_contours;
  }

  return bufp;
}
コード例 #5
0
ファイル: tabytecode.c プロジェクト: MechanisM/entypo
static FT_Byte*
TA_sfnt_build_glyph_scaler(SFNT* sfnt,
                           Recorder* recorder,
                           FT_Byte* bufp)
{
  FT_GlyphSlot glyph = sfnt->face->glyph;
  FT_Vector* points = glyph->outline.points;
  FT_Int num_contours = glyph->outline.n_contours;

  FT_UInt* args;
  FT_UInt* arg;
  FT_UInt num_args;
  FT_UInt nargs;

  FT_Bool need_words = 0;
  FT_Int p, q;
  FT_UInt i, j;
  FT_Int start, end;
  FT_UInt num_stack_elements;


  num_args = 2 * num_contours + 2;

  /* collect all arguments temporarily in an array (in reverse order) */
  /* so that we can easily split into chunks of 255 args */
  /* as needed by NPUSHB and NPUSHW, respectively */
  args = (FT_UInt*)malloc(num_args * sizeof (FT_UInt));
  if (!args)
    return NULL;

  arg = args + num_args - 1;

  if (num_args > 0xFF)
    need_words = 1;

  if (recorder->glyph->num_components)
    *(arg--) = bci_scale_composite_glyph;
  else
    *(arg--) = bci_scale_glyph;
  *(arg--) = num_contours;

  start = 0;
  end = 0;

  for (p = 0; p < num_contours; p++)
  {
    FT_Int max = start;
    FT_Int min = start;


    end = glyph->outline.contours[p];

    for (q = start; q <= end; q++)
    {
      if (points[q].y < points[min].y)
        min = q;
      if (points[q].y > points[max].y)
        max = q;
    }

    if (min > max)
    {
      *(arg--) = TA_adjust_point_index(recorder, max);
      *(arg--) = TA_adjust_point_index(recorder, min);
    }
    else
    {
      *(arg--) = TA_adjust_point_index(recorder, min);
      *(arg--) = TA_adjust_point_index(recorder, max);
    }

    start = end + 1;
  }

  if (end > 0xFF)
    need_words = 1;

  /* with most fonts it is very rare */
  /* that any of the pushed arguments is larger than 0xFF, */
  /* thus we refrain from further optimizing this case */

  arg = args;

  if (need_words)
  {
    for (i = 0; i < num_args; i += 255)
    {
      nargs = (num_args - i > 255) ? 255 : num_args - i;

      BCI(NPUSHW);
      BCI(nargs);
      for (j = 0; j < nargs; j++)
      {
        BCI(HIGH(*arg));
        BCI(LOW(*arg));
        arg++;
      }
    }
  }
  else
  {
    for (i = 0; i < num_args; i += 255)
    {
      nargs = (num_args - i > 255) ? 255 : num_args - i;

      BCI(NPUSHB);
      BCI(nargs);
      for (j = 0; j < nargs; j++)
      {
        BCI(*arg);
        arg++;
      }
    }
  }

  BCI(CALL);

  num_stack_elements = ADDITIONAL_STACK_ELEMENTS + num_args;
  if (num_stack_elements > sfnt->max_stack_elements)
    sfnt->max_stack_elements = num_stack_elements;

  free(args);

  return bufp;
}
コード例 #6
0
ファイル: taprep.c プロジェクト: goldcome/ttfautohint
static FT_Error
TA_table_build_prep(FT_Byte** prep,
                    FT_ULong* prep_len,
                    SFNT* sfnt,
                    FONT* font)
{
  SFNT_Table* glyf_table = &font->tables[sfnt->glyf_idx];
  glyf_Data* data = (glyf_Data*)glyf_table->data;
  /* XXX: make this work for more than 256 styles */
  FT_Byte num_used_styles = (FT_Byte)data->num_used_styles;

  FT_Int i;

  FT_Byte* buf = NULL;
  FT_Byte* buf_new;
  FT_UInt buf_len;
  FT_UInt buf_new_len;

  FT_UInt len;
  FT_Byte* bufp = NULL;


  if (font->x_height_snapping_exceptions)
  {
    bufp = TA_sfnt_build_number_set(sfnt, &buf,
                                    font->x_height_snapping_exceptions);
    if (!bufp)
      return FT_Err_Out_Of_Memory;
  }

  buf_len = (FT_UInt)(bufp - buf);
  buf_new_len = buf_len;

  if (font->hinting_limit)
    buf_new_len += sizeof (PREP(hinting_limit_a))
                   + 2
                   + sizeof (PREP(hinting_limit_b));

  buf_new_len += sizeof (PREP(store_funits_to_pixels));

  if (font->x_height_snapping_exceptions)
    buf_new_len += sizeof (PREP(test_exception_a));

  buf_new_len += sizeof (PREP(align_top_a))
                 + (num_used_styles > 6 ? num_used_styles + 3
                                        : num_used_styles + 2)
                 + sizeof (PREP(align_top_b));
  buf_new_len += sizeof (PREP(loop_cvt_a))
                 + (num_used_styles > 3 ? 2 * num_used_styles + 3
                                        : 2 * num_used_styles + 2)
                 + sizeof (PREP(loop_cvt_b))
                 + (num_used_styles > 3 ? 2 * num_used_styles + 3
                                        : 2 * num_used_styles + 2)
                 + sizeof (PREP(loop_cvt_c));

  if (font->x_height_snapping_exceptions)
    buf_new_len += sizeof (PREP(test_exception_b));

  buf_new_len += sizeof (PREP(store_vwidth_data_a))
                 + 1
                 + sizeof (PREP(store_vwidth_data_b))
                 + (num_used_styles > 6 ? 2 * (num_used_styles + 1) + 2
                                        : 2 * (num_used_styles + 1) + 1)
                 + sizeof (PREP(store_vwidth_data_c))
                 + 1
                 + sizeof (PREP(store_vwidth_data_d))
                 + (num_used_styles > 6 ? 2 * (num_used_styles + 1) + 2
                                        : 2 * (num_used_styles + 1) + 1)
                 + sizeof (PREP(store_vwidth_data_e));
  buf_new_len += sizeof (PREP(set_smooth_or_strong_a))
                 + 1
                 + sizeof (PREP(set_smooth_or_strong_b))
                 + 1
                 + sizeof (PREP(set_smooth_or_strong_c))
                 + 1
                 + sizeof (PREP(set_smooth_or_strong_d));
  buf_new_len += (num_used_styles > 3 ? 2 * num_used_styles + 3
                                      : 2 * num_used_styles + 2)
                 + sizeof (PREP(round_blues));
  buf_new_len += sizeof (PREP(set_dropout_mode));
  buf_new_len += sizeof (PREP(reset_component_counter));
  if (font->control_data_head)
    buf_new_len += sizeof (PREP(adjust_delta_exceptions));
  buf_new_len += sizeof (PREP(set_default_cvs_values));

  /* buffer length must be a multiple of four */
  len = (buf_new_len + 3) & ~3U;
  buf_new = (FT_Byte*)realloc(buf, len);
  if (!buf_new)
  {
    free(buf);
    return FT_Err_Out_Of_Memory;
  }
  buf = buf_new;

  /* pad end of buffer with zeros */
  buf[len - 1] = 0x00;
  buf[len - 2] = 0x00;
  buf[len - 3] = 0x00;

  /* copy remaining cvt program into buffer */
  /* and fill in the missing variables */
  bufp = buf + buf_len;

  if (font->hinting_limit)
  {
    COPY_PREP(hinting_limit_a);
    *(bufp++) = HIGH(font->hinting_limit);
    *(bufp++) = LOW(font->hinting_limit);
    COPY_PREP(hinting_limit_b);
  }

  COPY_PREP(store_funits_to_pixels);

  if (font->x_height_snapping_exceptions)
    COPY_PREP(test_exception_a);

  COPY_PREP(align_top_a);
  if (num_used_styles > 6)
  {
    BCI(NPUSHB);
    BCI(num_used_styles + 2);
  }
  else
    BCI(PUSHB_1 - 1 + num_used_styles + 2);
  /* XXX: make this work for offsets > 255 */
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    *(bufp++) = CVT_X_HEIGHT_BLUE_OFFSET(i) >= 0xFFFFU
                  ? 0
                  : (unsigned char)CVT_X_HEIGHT_BLUE_OFFSET(i);
  }
  *(bufp++) = num_used_styles;
  COPY_PREP(align_top_b);

  COPY_PREP(loop_cvt_a);
  if (num_used_styles > 3)
  {
    BCI(NPUSHB);
    BCI(2 * num_used_styles + 2);
  }
  else
    BCI(PUSHB_1 - 1 + 2 * num_used_styles + 2);
  /* XXX: make this work for offsets > 255 */
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    /* don't loop over artificial blue zones */
    *(bufp++) = (unsigned char)CVT_VERT_STANDARD_WIDTH_OFFSET(i);
    *(bufp++) = (unsigned char)(
                  1
                  + CVT_VERT_WIDTHS_SIZE(i)
                  + (CVT_BLUES_SIZE(i) > 1 ? CVT_BLUES_SIZE(i) - 2 : 0));
  }
  *(bufp++) = num_used_styles;
  COPY_PREP(loop_cvt_b);
  if (num_used_styles > 3)
  {
    BCI(NPUSHB);
    BCI(2 * num_used_styles + 2);
  }
  else
    BCI(PUSHB_1 - 1 + 2 * num_used_styles + 2);
  /* XXX: make this work for offsets > 255 */
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    /* don't loop over artificial blue zones */
    *(bufp++) = (unsigned char)CVT_BLUE_SHOOTS_OFFSET(i);
    *(bufp++) = (unsigned char)(
                  CVT_BLUES_SIZE(i) > 1 ? CVT_BLUES_SIZE(i) - 2 : 0);
  }
  *(bufp++) = num_used_styles;
  COPY_PREP(loop_cvt_c);

  if (font->x_height_snapping_exceptions)
    COPY_PREP(test_exception_b);

  COPY_PREP(store_vwidth_data_a);
  *(bufp++) = (unsigned char)CVT_VWIDTH_OFFSET_DATA(0);
  COPY_PREP(store_vwidth_data_b);
  if (num_used_styles > 6)
  {
    BCI(NPUSHW);
    BCI(num_used_styles + 2);
  }
  else
    BCI(PUSHW_1 - 1 + num_used_styles + 2);
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    *(bufp++) = HIGH(CVT_VERT_WIDTHS_OFFSET(i) * 64);
    *(bufp++) = LOW(CVT_VERT_WIDTHS_OFFSET(i) * 64);
  }
  *(bufp++) = HIGH(num_used_styles);
  *(bufp++) = LOW(num_used_styles);
  COPY_PREP(store_vwidth_data_c);
  *(bufp++) = (unsigned char)CVT_VWIDTH_SIZE_DATA(0);
  COPY_PREP(store_vwidth_data_d);
  if (num_used_styles > 6)
  {
    BCI(NPUSHW);
    BCI(num_used_styles + 2);
  }
  else
    BCI(PUSHW_1 - 1 + num_used_styles + 2);
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    *(bufp++) = HIGH(CVT_VERT_WIDTHS_SIZE(i) * 64);
    *(bufp++) = LOW(CVT_VERT_WIDTHS_SIZE(i) * 64);
  }
  *(bufp++) = HIGH(num_used_styles);
  *(bufp++) = LOW(num_used_styles);
  COPY_PREP(store_vwidth_data_e);

  COPY_PREP(set_smooth_or_strong_a);
  *(bufp++) = font->gray_strong_stem_width ? 100 : 0;
  COPY_PREP(set_smooth_or_strong_b);
  *(bufp++) = font->gdi_cleartype_strong_stem_width ? 100 : 0;
  COPY_PREP(set_smooth_or_strong_c);
  *(bufp++) = font->dw_cleartype_strong_stem_width ? 100 : 0;
  COPY_PREP(set_smooth_or_strong_d);

  if (num_used_styles > 3)
  {
    BCI(NPUSHB);
    BCI(2 * num_used_styles + 2);
  }
  else
    BCI(PUSHB_1 - 1 + 2 * num_used_styles + 2);
  /* XXX: make this work for offsets > 255 */
  for (i = TA_STYLE_MAX - 1; i >= 0; i--)
  {
    if (data->style_ids[i] == 0xFFFFU)
      continue;

    *(bufp++) = (unsigned char)CVT_BLUE_REFS_OFFSET(i);
    *(bufp++) = (unsigned char)CVT_BLUES_SIZE(i);
  }
  *(bufp++) = num_used_styles;
  COPY_PREP(round_blues);

  COPY_PREP(set_dropout_mode);
  COPY_PREP(reset_component_counter);
  if (font->control_data_head)
    COPY_PREP(adjust_delta_exceptions);
  COPY_PREP(set_default_cvs_values);

  *prep = buf;
  *prep_len = buf_new_len;

  return FT_Err_Ok;
}
コード例 #7
0
ファイル: taprep.c プロジェクト: goldcome/ttfautohint
static FT_Byte*
TA_sfnt_build_number_set(SFNT* sfnt,
                         FT_Byte** buf,
                         number_range* number_set)
{
  FT_Byte* bufp = NULL;
  number_range* nr;

  FT_UInt num_singles2 = 0;
  FT_UInt* single2_args;
  FT_UInt* single2_arg;
  FT_UInt num_singles = 0;
  FT_UInt* single_args;
  FT_UInt* single_arg;

  FT_UInt num_ranges2 = 0;
  FT_UInt* range2_args;
  FT_UInt* range2_arg;
  FT_UInt num_ranges = 0;
  FT_UInt* range_args;
  FT_UInt* range_arg;

  FT_UInt have_single = 0;
  FT_UInt have_range = 0;

  FT_UShort num_stack_elements;


  /* build up four stacks to stay as compact as possible */
  nr = number_set;
  while (nr)
  {
    if (nr->start == nr->end)
    {
      if (nr->start < 256)
        num_singles++;
      else
        num_singles2++;
    }
    else
    {
      if (nr->start < 256 && nr->end < 256)
        num_ranges++;
      else
        num_ranges2++;
    }
    nr = nr->next;
  }

  /* collect all arguments temporarily in arrays (in reverse order) */
  /* so that we can easily split into chunks of 255 args */
  /* as needed by NPUSHB and friends; */
  /* for simplicity, always allocate an extra slot */
  single2_args = (FT_UInt*)malloc((num_singles2 + 1) * sizeof (FT_UInt));
  single_args = (FT_UInt*)malloc((num_singles + 1) * sizeof (FT_UInt));
  range2_args = (FT_UInt*)malloc((2 * num_ranges2 + 1) * sizeof (FT_UInt));
  range_args = (FT_UInt*)malloc((2 * num_ranges + 1) * sizeof (FT_UInt));
  if (!single2_args || !single_args
      || !range2_args || !range_args)
    goto Fail;

  /* check whether we need the extra slot for the argument to CALL */
  if (num_singles || num_singles2)
    have_single = 1;
  if (num_ranges || num_ranges2)
    have_range = 1;

  /* set function indices outside of argument loop (using the extra slot) */
  if (have_single)
    single_args[num_singles] = bci_number_set_is_element;
  if (have_range)
    range_args[2 * num_ranges] = bci_number_set_is_element2;

  single2_arg = single2_args + num_singles2 - 1;
  single_arg = single_args + num_singles - 1;
  range2_arg = range2_args + 2 * num_ranges2 - 1;
  range_arg = range_args + 2 * num_ranges - 1;

  nr = number_set;
  while (nr)
  {
    FT_UInt start = (FT_UInt)nr->start;
    FT_UInt end = (FT_UInt)nr->end;


    if (start == end)
    {
      if (start < 256)
        *(single_arg--) = start;
      else
        *(single2_arg--) = start;
    }
    else
    {
      if (start < 256 && end < 256)
      {
        *(range_arg--) = start;
        *(range_arg--) = end;
      }
      else
      {
        *(range2_arg--) = start;
        *(range2_arg--) = end;
      }
    }
    nr = nr->next;
  }

  /* this rough estimate of the buffer size gets adjusted later on */
  *buf = (FT_Byte*)malloc((2 + 1) * num_singles2
                          + (1 + 1) * num_singles
                          + (4 + 1) * num_ranges2
                          + (2 + 1) * num_ranges
                          + 10);
  if (!*buf)
    goto Fail;
  bufp = *buf;

  BCI(PUSHB_2);
    BCI(cvtl_is_element);
    BCI(0);
  BCI(WCVTP);

  bufp = TA_build_push(bufp, single2_args, num_singles2, 1, 1);
  bufp = TA_build_push(bufp, single_args, num_singles + have_single, 0, 1);
  if (have_single)
    BCI(CALL);

  bufp = TA_build_push(bufp, range2_args, 2 * num_ranges2, 1, 1);
  bufp = TA_build_push(bufp, range_args, 2 * num_ranges + have_range, 0, 1);
  if (have_range)
    BCI(CALL);

  num_stack_elements = (FT_UShort)(num_singles + num_singles2);
  if (num_stack_elements > num_ranges + num_ranges2)
    num_stack_elements = (FT_UShort)(num_ranges + num_ranges2);
  num_stack_elements += ADDITIONAL_STACK_ELEMENTS;
  if (num_stack_elements > sfnt->max_stack_elements)
    sfnt->max_stack_elements = num_stack_elements;

Fail:
  free(single2_args);
  free(single_args);
  free(range2_args);
  free(range_args);

  return bufp;
}