Exemple #1
0
SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
    fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
    int index;
    std::unique_ptr<SkStreamAsset> asset(fImpl->fTypeface->openStream(&index));
    size_t size = asset->getLength();
    SkAutoMalloc autoMalloc(size);  // TODO(halcanary): Avoid this malloc+copy.
    asset->read(autoMalloc.get(), size);
    asset = nullptr;
    void* ptr = autoMalloc.get();
    hb_blob_t* blob = hb_blob_create((char*)autoMalloc.release(), size,
                                     HB_MEMORY_MODE_READONLY, ptr, sk_free);
    SkASSERT(blob);
    hb_blob_make_immutable(blob);

    struct HBFaceDel {
        void operator()(hb_face_t* f) { hb_face_destroy(f); }
    };
    std::unique_ptr<hb_face_t, HBFaceDel> face(hb_face_create(blob, (unsigned)index));
    hb_blob_destroy(blob);
    SkASSERT(face);
    if (!face) {
        return;
    }
    hb_face_set_index(face.get(), (unsigned)index);
    hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm());

    fImpl->fHarfBuzzFont.reset(hb_font_create(face.get()));
    SkASSERT(fImpl->fHarfBuzzFont);
    hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCALE);
    hb_ot_font_set_funcs(fImpl->fHarfBuzzFont.get());

    fImpl->fBuffer.reset(hb_buffer_create());
}
Exemple #2
0
static hb_blob_t *
icu_le_hb_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
{
  const LEFontInstance *fontInstance = (const LEFontInstance *) user_data;

  size_t length = 0;
  const char *data = (const char *) fontInstance->getFontTable (tag, length);

  return hb_blob_create (data, length, HB_MEMORY_MODE_READONLY, NULL, NULL);
}
static hb_blob_t* harfBuzzCoreTextGetTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
    CGFontRef cgFont = reinterpret_cast<CGFontRef>(userData);
    CFDataRef cfData = CGFontCopyTableForTag(cgFont, tag);
    if (!cfData)
        return 0;

    const char* data = reinterpret_cast<const char*>(CFDataGetBytePtr(cfData));
    const size_t length = CFDataGetLength(cfData);
    if (!data || !length)
        return 0;
    return hb_blob_create(data, length, HB_MEMORY_MODE_READONLY, reinterpret_cast<void*>(const_cast<__CFData*>(cfData)), releaseTableData);
}
Exemple #4
0
int glyphwidth (lua_State* L) {
  size_t font_l;
  unsigned int gid = luaL_checknumber(L, 1);
  const char * font_s = luaL_checklstring(L, 2, &font_l);
  unsigned int font_index = luaL_checknumber(L, 3);
  hb_blob_t* blob = hb_blob_create (font_s, font_l, HB_MEMORY_MODE_WRITABLE, (void*)font_s, NULL);
  hb_face_t* hbFace = hb_face_create (blob, font_index);
  hb_font_t* hbFont = hb_font_create (hbFace);
  short upem = hb_face_get_upem(hbFace);
  hb_ft_font_set_funcs(hbFont);
  hb_position_t width = hb_font_get_glyph_h_advance(hbFont, gid);
  lua_pushnumber(L, width / (double)upem);
  return 1;
}
Exemple #5
0
int get_typographic_extents (lua_State *L) {
  size_t font_l;
  const char * font_s = luaL_checklstring(L, 1, &font_l);
  unsigned int font_index = luaL_checknumber(L, 2);
  short upem;
  double ascender;
  double descender;
  double x_height;

#ifdef USE_FREETYPE_METRICS
  if (!library) FT_Init_FreeType (&library);
  FT_Face ft_face = NULL;
  FT_Error err = FT_New_Memory_Face (library,
    (const FT_Byte *) font_s, font_l, font_index, &ft_face);
  if(err) { luaL_error(L, "FT_New_Memory_Face failed"); }
  upem = ft_face->units_per_EM;
  ascender = ft_face->ascender / (double)upem;
  descender = -ft_face->descender / (double)upem;
  TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(ft_face, ft_sfnt_os2);
  if (os2) {
    x_height = os2->sxHeight / (double)upem;
  }
  FT_Done_Face(ft_face);
#else
  hb_blob_t* blob = hb_blob_create (font_s, font_l, HB_MEMORY_MODE_WRITABLE, (void*)font_s, NULL);
  hb_face_t* hbFace = hb_face_create (blob, font_index);
  hb_font_t* hbFont = hb_font_create (hbFace);
  hb_font_extents_t metrics = {0,0,0};
  upem = hb_face_get_upem(hbFace);
  hb_ft_font_set_funcs(hbFont);
  hb_font_get_h_extents(hbFont, &metrics);
  ascender = metrics.ascender / (double)upem;
  descender = metrics.descender / (double)upem;
  hb_font_destroy(hbFont);
#endif

  lua_newtable(L);
  lua_pushstring(L, "ascender");
  lua_pushnumber(L, ascender);
  lua_settable(L, -3);
  lua_pushstring(L, "x_height");
  lua_pushnumber(L, x_height);
  lua_settable(L, -3);
  lua_pushstring(L, "descender");
  lua_pushnumber(L, descender);
  lua_settable(L, -3);

  return 1;
}
Exemple #6
0
hb_blob_t *
gfxDWriteFont::GetFontTable(PRUint32 aTag)
{
    const void *data;
    UINT32      size;
    void       *context;
    BOOL        exists;
    HRESULT hr = mFontFace->TryGetFontTable(NS_SWAP32(aTag),
                                            &data, &size, &context, &exists);
    if (SUCCEEDED(hr) && exists) {
        FontTableRec *ftr = new FontTableRec(mFontFace, context);
        return hb_blob_create(static_cast<const char*>(data), size,
                              HB_MEMORY_MODE_READONLY,
                              DestroyBlobFunc, ftr);
    }

    return hb_blob_create_empty();
}
static hb_blob_t* harfBuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
    SkTypeface* typeface = reinterpret_cast<SkTypeface*>(userData);

    const size_t tableSize = typeface->getTableSize(tag);
    if (!tableSize)
        return 0;

    char* buffer = reinterpret_cast<char*>(fastMalloc(tableSize));
    if (!buffer)
        return 0;
    size_t actualSize = typeface->getTableData(tag, 0, tableSize, buffer);
    if (tableSize != actualSize) {
        fastFree(buffer);
        return 0;
    }

    return hb_blob_create(const_cast<char*>(buffer), tableSize, HB_MEMORY_MODE_WRITABLE, buffer, fastFree);
}
Exemple #8
0
static hb_blob_t* harfbuzzSkiaGetTable(hb_face_t* face, hb_tag_t tag, void* userData)
{
    FontPlatformData* font = reinterpret_cast<FontPlatformData*>(userData);

    const size_t tableSize = SkFontHost::GetTableSize(font->uniqueID(), tag);
    if (!tableSize)
        return 0;

    char* buffer = reinterpret_cast<char*>(fastMalloc(tableSize));
    if (!buffer)
        return 0;
    size_t actualSize = SkFontHost::GetTableData(font->uniqueID(), tag, 0, tableSize, buffer);
    if (tableSize != actualSize) {
        fastFree(buffer);
        return 0;
    }

    return hb_blob_create(const_cast<char*>(buffer), tableSize,
                          HB_MEMORY_MODE_WRITABLE, buffer, fastFree);
}
Exemple #9
0
static hb_blob_t* referenceTable(hb_face_t*, hb_tag_t tag, void *userData)
{
	FT_Face ftFace = reinterpret_cast<FT_Face>(userData);
	FT_Byte *buffer;
	FT_ULong length = 0;

	if (FT_Load_Sfnt_Table(ftFace, tag, 0, NULL, &length))
		return NULL;

	buffer = reinterpret_cast<FT_Byte*>(malloc(length));
	if (buffer == NULL)
		return NULL;

	if (FT_Load_Sfnt_Table(ftFace, tag, 0, buffer, &length))
	{
		free(buffer);
		return NULL;
	}

	return hb_blob_create((const char *) buffer, length, HB_MEMORY_MODE_WRITABLE, buffer, free);
}
Exemple #10
0
/**
 * pango_ot_info_get:
 * @face: a <type>FT_Face</type>.
 *
 * Returns the #PangoOTInfo structure for the given FreeType font face.
 *
 * Return value: the #PangoOTInfo for @face. This object will have
 * the same lifetime as @face.
 *
 * Since: 1.2
 **/
PangoOTInfo *
pango_ot_info_get (FT_Face face)
{
  PangoOTInfo *info;

  if (G_LIKELY (face->generic.data && face->generic.finalizer == pango_ot_info_finalizer))
    return face->generic.data;
  else
    {
      if (face->generic.finalizer)
        face->generic.finalizer (face);

      info = face->generic.data = g_object_new (PANGO_TYPE_OT_INFO, NULL);
      face->generic.finalizer = pango_ot_info_finalizer;

      info->face = face;

      if (face->stream->read == NULL) {
	hb_blob_t *blob;

	blob = hb_blob_create ((const char *) face->stream->base,
			       (unsigned int) face->stream->size,
			       HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
			       NULL, NULL);
	info->hb_face = hb_face_create_for_data (blob, face->face_index);
	hb_blob_destroy (blob);
      } else {
	info->hb_face = hb_face_create_for_tables (_get_table, NULL, info);
      }


      hb_face_set_unicode_funcs (info->hb_face, hb_glib_get_unicode_funcs ());

      /* XXX this is such a waste if not SFNT */
      if (!hb_ot_layout_has_font_glyph_classes (info->hb_face))
	synthesize_class_def (info);
    }

  return info;
}
Exemple #11
0
static hb_blob_t *
_get_table(hb_face_t *, hb_tag_t tag, void *user_data)
{
    FT_Face face = (FT_Face) user_data;
    FT_ULong length = 0;
    FT_Byte *table;
    FT_Error error;
    hb_blob_t* blob = NULL;

    error = FT_Load_Sfnt_Table(face, tag, 0, NULL, &length);
    if (!error) {
        table = (FT_Byte *) xmalloc(length * sizeof(char));
        if (table != NULL) {
            error = FT_Load_Sfnt_Table(face, tag, 0, (FT_Byte*)table, &length);
            if (!error) {
                blob = hb_blob_create((const char*) table, length, HB_MEMORY_MODE_WRITABLE, table, free);
            } else {
                free(table);
            }
        }
    }

    return blob;
}
Exemple #12
0
static hb_blob_t *
_get_table  (hb_tag_t tag, void *user_data)
{
  PangoOTInfo *info = (PangoOTInfo *) user_data;
  FT_Byte *buffer;
  FT_ULong  length = 0;
  FT_Error error;

  error = FT_Load_Sfnt_Table (info->face, tag, 0, NULL, &length);
  if (error)
    return hb_blob_create_empty ();

  buffer = g_malloc (length);
  if (buffer == NULL)
    return hb_blob_create_empty ();

  error = FT_Load_Sfnt_Table (info->face, tag, 0, buffer, &length);
  if (error)
    return hb_blob_create_empty ();

  return hb_blob_create ((const char *) buffer, length,
			 HB_MEMORY_MODE_WRITABLE,
			 g_free, buffer);
}
Exemple #13
0
int shape (lua_State *L) {    
    size_t font_l;
    const char * text = luaL_checkstring(L, 1);
    const char * font_s = luaL_checklstring(L, 2, &font_l);
    unsigned int font_index = luaL_checknumber(L, 3);
    const char * script = luaL_checkstring(L, 4);
    const char * direction_s = luaL_checkstring(L, 5);
    const char * lang = luaL_checkstring(L, 6);
    double point_size = luaL_checknumber(L, 7);
    const char * featurestring = luaL_checkstring(L, 8);

    hb_segment_properties_t segment_props;
    hb_shape_plan_t *shape_plan;

    hb_direction_t direction;
    hb_feature_t* features;
    int nFeatures = 0;
    unsigned int glyph_count = 0;
    hb_font_t *hbFont;
    hb_buffer_t *buf;
    hb_glyph_info_t *glyph_info;
    hb_glyph_position_t *glyph_pos;
    unsigned int j;

    features = scan_feature_string(featurestring, &nFeatures);

    if (!strcasecmp(direction_s,"RTL"))
      direction = HB_DIRECTION_RTL;
    else if (!strcasecmp(direction_s,"TTB"))
      direction = HB_DIRECTION_TTB;
    else
      direction = HB_DIRECTION_LTR;

    hb_blob_t* blob = hb_blob_create (font_s, font_l, HB_MEMORY_MODE_WRITABLE, (void*)font_s, NULL);
    hb_face_t* hbFace = hb_face_create (blob, font_index);
    hbFont = hb_font_create (hbFace);
    unsigned int upem = hb_face_get_upem(hbFace);
    hb_font_set_scale(hbFont, upem, upem);

    /* Harfbuzz's support for OT fonts is great, but
       there's currently no support for CFF fonts, so
       downgrade to Freetype for those. */
    if (strncmp(font_s, "OTTO", 4) == 0) {
      hb_ft_font_set_funcs(hbFont);
    } else {
      hb_ot_font_set_funcs(hbFont);
    }

    buf = hb_buffer_create();
    hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text));

    hb_buffer_set_script(buf, hb_tag_from_string(script, strlen(script)));
    hb_buffer_set_direction(buf, direction);
    hb_buffer_set_language(buf, hb_language_from_string(lang,strlen(lang)));

    hb_buffer_guess_segment_properties(buf);
    hb_buffer_get_segment_properties(buf, &segment_props);
    shape_plan = hb_shape_plan_create_cached(hbFace, &segment_props, features, nFeatures, NULL);
    int res = hb_shape_plan_execute(shape_plan, hbFont, buf, features, nFeatures);

    if (direction == HB_DIRECTION_RTL) {
      hb_buffer_reverse(buf); /* URGH */
    }
    glyph_info   = hb_buffer_get_glyph_infos(buf, &glyph_count);
    glyph_pos    = hb_buffer_get_glyph_positions(buf, &glyph_count);
    lua_checkstack(L, glyph_count);
    for (j = 0; j < glyph_count; ++j) {
      char namebuf[255];
      hb_glyph_extents_t extents = {0,0,0,0};
      hb_font_get_glyph_extents(hbFont, glyph_info[j].codepoint, &extents);

      lua_newtable(L);
      lua_pushstring(L, "name");
      hb_font_get_glyph_name( hbFont, glyph_info[j].codepoint, namebuf, 255 );
      lua_pushstring(L, namebuf);
      lua_settable(L, -3);

      /* We don't apply x-offset and y-offsets for TTB, which
      is arguably a bug. We should. The reason we don't is that
      Harfbuzz assumes that you want to shift the character from a
      top-center baseline to a bottom-left baseline, and gives you
      offsets which do that. We don't want to do that so we ignore the
      offsets. I'm told there is a way of configuring HB's idea of the
      baseline, and we should use that and take out this condition. */
      if (direction != HB_DIRECTION_TTB) {
        if (glyph_pos[j].x_offset) {
          lua_pushstring(L, "x_offset");
          lua_pushnumber(L, glyph_pos[j].x_offset * point_size / upem);
          lua_settable(L, -3);
        }

        if (glyph_pos[j].y_offset) {
          lua_pushstring(L, "y_offset");
          lua_pushnumber(L, glyph_pos[j].y_offset * point_size / upem);
          lua_settable(L, -3);
        }
      }

      lua_pushstring(L, "codepoint");
      lua_pushinteger(L, glyph_info[j].codepoint);
      lua_settable(L, -3);
      lua_pushstring(L, "index");
      lua_pushinteger(L, glyph_info[j].cluster);
      lua_settable(L, -3);

      double height = extents.y_bearing * point_size / upem;
      double tHeight = extents.height * point_size / upem;
      double width = glyph_pos[j].x_advance * point_size / upem;

      /* The PDF model expects us to make positioning adjustments
      after a glyph is painted. For this we need to know the natural
      glyph advance. libtexpdf will use this to compute the adjustment. */
      double glyphAdvance = hb_font_get_glyph_h_advance(hbFont, glyph_info[j].codepoint) * point_size / upem;

      if (direction == HB_DIRECTION_TTB) {
        height = -glyph_pos[j].y_advance * point_size / upem;
        tHeight = -height; /* Set depth to 0 - depth has no meaning for TTB */
        width = glyphAdvance;
        glyphAdvance = height;
      }
      lua_pushstring(L, "glyphAdvance");
      lua_pushnumber(L, glyphAdvance);
      lua_settable(L, -3);

      lua_pushstring(L, "width");
      lua_pushnumber(L, width);
      lua_settable(L, -3);

      lua_pushstring(L, "height");
      lua_pushnumber(L, height);
      lua_settable(L, -3);
      lua_pushstring(L, "depth");
      lua_pushnumber(L, -tHeight - height);
      lua_settable(L, -3);
    }
    /* Cleanup */
    hb_buffer_destroy(buf);
    hb_font_destroy(hbFont);
    hb_shape_plan_destroy(shape_plan);

    free(features);
    return glyph_count;
}
Exemple #14
0
static void *
create_blob_inert (void)
{
  return hb_blob_create (NULL, 0, HB_MEMORY_MODE_DUPLICATE, NULL, NULL);
}
Exemple #15
0
static void *
create_blob (void)
{
  static char data[] = "test data";
  return hb_blob_create (data, sizeof (data), HB_MEMORY_MODE_READONLY, NULL, NULL);
}