Esempio n. 1
0
FT_Error
TA_sfnt_update_hmtx_table(SFNT* sfnt,
                          FONT* font)
{
  SFNT_Table* hmtx_table;
  FT_Byte* buf_new;
  FT_ULong buf_len;
  FT_ULong i;


  if (sfnt->hmtx_idx == MISSING)
    return TA_Err_Ok;

  hmtx_table = &font->tables[sfnt->hmtx_idx];

  if (hmtx_table->processed)
    return TA_Err_Ok;

  /* the metrics of the added composite element doesn't matter; */
  /* for this reason, we simply append two zero bytes, */
  /* indicating a zero value in the `leftSideBearing' array */
  /* (this works because we don't increase the `numberOfHMetrics' field) */

  hmtx_table->len += 2;
  /* make the allocated buffer length a multiple of 4 */
  buf_len = (hmtx_table->len + 3) & ~3;
  buf_new = (FT_Byte*)realloc(hmtx_table->buf, buf_len);
  if (!buf_new)
  {
    hmtx_table->len -= 2;
    return FT_Err_Out_Of_Memory;
  }

  /* pad end of buffer with zeros */
  for (i = hmtx_table->len - 2; i < buf_len; i++)
    buf_new[i] = 0x00;

  hmtx_table->buf = buf_new;
  hmtx_table->checksum = TA_table_compute_checksum(hmtx_table->buf,
                                                   hmtx_table->len);
  hmtx_table->processed = 1;

  return TA_Err_Ok;
}
Esempio n. 2
0
FT_Error
TA_font_add_table(FONT* font,
                  SFNT_Table_Info* table_info,
                  FT_ULong tag,
                  FT_ULong len,
                  FT_Byte* buf)
{
    SFNT_Table* tables_new;
    SFNT_Table* table_last;


    font->num_tables++;
    tables_new = (SFNT_Table*)realloc(font->tables,
                                      font->num_tables * sizeof (SFNT_Table));
    if (!tables_new)
    {
        font->num_tables--;
        return FT_Err_Out_Of_Memory;
    }
    else
        font->tables = tables_new;

    table_last = &font->tables[font->num_tables - 1];

    table_last->tag = tag;
    table_last->len = len;
    table_last->buf = buf;
    table_last->checksum = TA_table_compute_checksum(buf, len);
    table_last->offset = 0; /* set in `TA_font_compute_table_offsets' */
    table_last->data = NULL;
    table_last->processed = 0;

    /* link table and table info */
    *table_info = font->num_tables - 1;

    return TA_Err_Ok;
}
Esempio n. 3
0
FT_Error
TA_sfnt_update_name_table(SFNT* sfnt,
                          FONT* font)
{
  FT_Error error;

  SFNT_Table* name_table;
  FT_Byte* buf;
  FT_ULong buf_len;

  Naming_Table n;

  FT_Byte* p;
  FT_Byte* startp;
  FT_Byte* endp;

  FT_UShort i;


  if (sfnt->name_idx == MISSING)
    return TA_Err_Ok;

  name_table = &font->tables[sfnt->name_idx];
  buf = name_table->buf;
  buf_len = name_table->len;

  if (name_table->processed)
    return TA_Err_Ok;

  p = buf;

  error = parse_name_header(&p, &n, buf_len, &startp, &endp);
  if (error)
    return TA_Err_Ok;

  /* due to the structure of the `name' table, */
  /* we must parse it completely, apply our changes, */
  /* and rebuild it from scratch */
  error = parse_name_records(&p, &n, buf, startp, endp, font);
  if (error)
    goto Exit;

  error = parse_lang_tag_records(&p, &n, buf, startp, endp);
  if (error)
    goto Exit;

  error = build_name_table(&n, name_table);
  if (error)
    goto Exit;

  name_table->checksum = TA_table_compute_checksum(name_table->buf,
                                                   name_table->len);

Exit:
  for (i = 0; i < n.name_count; i++)
    free(n.name_records[i].str);
  for (i = 0; i < n.lang_tag_count; i++)
    free(n.lang_tag_records[i].str);

  free(n.name_records);
  free(n.lang_tag_records);

  name_table->processed = 1;

  return error;
}
Esempio n. 4
0
FT_Error
TA_sfnt_build_TTF_header(SFNT* sfnt,
                         FONT* font,
                         FT_Byte** header_buf,
                         FT_ULong* header_len,
                         FT_Int do_complete)
{
  SFNT_Table* tables = font->tables;

  SFNT_Table_Info* table_infos = sfnt->table_infos;
  FT_ULong num_table_infos = sfnt->num_table_infos;

  FT_Byte* buf;
  FT_ULong len;

  FT_Byte* table_record;

  FT_Byte* head_buf = NULL; /* pointer to `head' table */
  FT_ULong head_checksum; /* checksum in `head' table */

  FT_ULong num_tables_in_header;
  FT_ULong i;


  num_tables_in_header = 0;
  for (i = 0; i < num_table_infos; i++)
  {
    /* ignore empty tables */
    if (table_infos[i] != MISSING)
      num_tables_in_header++;
  }

  len = 12 + 16 * num_tables_in_header;
  if (!do_complete)
  {
    *header_len = len;
    return TA_Err_Ok;
  }
  buf = (FT_Byte*)malloc(len);
  if (!buf)
    return FT_Err_Out_Of_Memory;

  /* SFNT version */
  buf[0] = 0x00;
  buf[1] = 0x01;
  buf[2] = 0x00;
  buf[3] = 0x00;

  /* number of tables */
  buf[4] = HIGH(num_tables_in_header);
  buf[5] = LOW(num_tables_in_header);

  /* auxiliary data */
  {
    FT_ULong search_range, entry_selector, range_shift;
    FT_ULong i, j;


    for (i = 1, j = 2; j <= num_tables_in_header; i++, j <<= 1)
      ;

    entry_selector = i - 1;
    search_range = 0x10 << entry_selector;
    range_shift = (num_tables_in_header << 4) - search_range;

    buf[6] = HIGH(search_range);
    buf[7] = LOW(search_range);
    buf[8] = HIGH(entry_selector);
    buf[9] = LOW(entry_selector);
    buf[10] = HIGH(range_shift);
    buf[11] = LOW(range_shift);
  }

  /* location of the first table info record */
  table_record = &buf[12];

  head_checksum = 0;

  /* loop over all tables */
  for (i = 0; i < num_table_infos; i++)
  {
    SFNT_Table_Info table_info = table_infos[i];
    SFNT_Table* table;


    /* ignore empty slots */
    if (table_info == MISSING)
      continue;

    table = &tables[table_info];

    if (table->tag == TTAG_head)
    {
      FT_ULong date_high;
      FT_ULong date_low;


      /* we always reach this IF clause since FreeType would */
      /* have aborted already if the `head' table were missing */

      head_buf = table->buf;

      /* reset checksum in `head' table for recalculation */
      head_buf[8] = 0x00;
      head_buf[9] = 0x00;
      head_buf[10] = 0x00;
      head_buf[11] = 0x00;

      /* update modification time */
      TA_get_current_time(&date_high, &date_low);

      head_buf[28] = BYTE1(date_high);
      head_buf[29] = BYTE2(date_high);
      head_buf[30] = BYTE3(date_high);
      head_buf[31] = BYTE4(date_high);

      head_buf[32] = BYTE1(date_low);
      head_buf[33] = BYTE2(date_low);
      head_buf[34] = BYTE3(date_low);
      head_buf[35] = BYTE4(date_low);

      table->checksum = TA_table_compute_checksum(table->buf, table->len);
    }

    head_checksum += table->checksum;

    table_record[0] = BYTE1(table->tag);
    table_record[1] = BYTE2(table->tag);
    table_record[2] = BYTE3(table->tag);
    table_record[3] = BYTE4(table->tag);

    table_record[4] = BYTE1(table->checksum);
    table_record[5] = BYTE2(table->checksum);
    table_record[6] = BYTE3(table->checksum);
    table_record[7] = BYTE4(table->checksum);

    table_record[8] = BYTE1(table->offset);
    table_record[9] = BYTE2(table->offset);
    table_record[10] = BYTE3(table->offset);
    table_record[11] = BYTE4(table->offset);

    table_record[12] = BYTE1(table->len);
    table_record[13] = BYTE2(table->len);
    table_record[14] = BYTE3(table->len);
    table_record[15] = BYTE4(table->len);

    table_record += 16;
  }

  /* the font header is complete; compute `head' checksum */
  head_checksum += TA_table_compute_checksum(buf, len);
  head_checksum = 0xB1B0AFBAUL - head_checksum;

  /* store checksum in `head' table; */
  head_buf[8] = BYTE1(head_checksum);
  head_buf[9] = BYTE2(head_checksum);
  head_buf[10] = BYTE3(head_checksum);
  head_buf[11] = BYTE4(head_checksum);

  *header_buf = buf;
  *header_len = len;

  return TA_Err_Ok;
}