commit
7633b7695e
18 changed files with 1079 additions and 29 deletions
@ -0,0 +1,223 @@ |
||||
/*
|
||||
* Copyright © 2019-2020 Ebrahim Byagowi |
||||
* |
||||
* This is part of HarfBuzz, a text shaping library. |
||||
* |
||||
* Permission is hereby granted, without written agreement and without |
||||
* license or royalty fees, to use, copy, modify, and distribute this |
||||
* software and its documentation for any purpose, provided that the |
||||
* above copyright notice and the following two paragraphs appear in |
||||
* all copies of this software. |
||||
* |
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
||||
* DAMAGE. |
||||
* |
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||
*/ |
||||
|
||||
#include "hb.hh" |
||||
|
||||
#ifndef HB_NO_OT_GLYPH |
||||
|
||||
#include "hb-ot.h" |
||||
#include "hb-ot-glyf-table.hh" |
||||
#include "hb-ot-cff1-table.hh" |
||||
#include "hb-ot-cff2-table.hh" |
||||
#include "hb-ot-glyph.hh" |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_move_to_func: |
||||
* @funcs: decompose functions object |
||||
* @move_to: move-to callback |
||||
* |
||||
* Sets move-to callback to the decompose functions object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_set_move_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_move_to_func_t move_to) |
||||
{ |
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return; |
||||
funcs->move_to = move_to; |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_line_to_func: |
||||
* @funcs: decompose functions object |
||||
* @line_to: line-to callback |
||||
* |
||||
* Sets line-to callback to the decompose functions object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_set_line_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_line_to_func_t line_to) |
||||
{ |
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return; |
||||
funcs->line_to = line_to; |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_conic_to_func: |
||||
* @funcs: decompose functions object |
||||
* @move_to: conic-to callback |
||||
* |
||||
* Sets conic-to callback to the decompose functions object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_conic_to_func_t conic_to) |
||||
{ |
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return; |
||||
funcs->conic_to = conic_to; |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_cubic_to_func: |
||||
* @funcs: decompose functions |
||||
* @cubic_to: cubic-to callback |
||||
* |
||||
* Sets cubic-to callback to the decompose functions object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_cubic_to_func_t cubic_to) |
||||
{ |
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return; |
||||
funcs->cubic_to = cubic_to; |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_set_close_path_func: |
||||
* @funcs: decompose functions object |
||||
* @close_path: close-path callback |
||||
* |
||||
* Sets close-path callback to the decompose functions object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_close_path_func_t close_path) |
||||
{ |
||||
if (unlikely (funcs == &Null (hb_ot_glyph_decompose_funcs_t))) return; |
||||
funcs->close_path = close_path; |
||||
} |
||||
|
||||
static void |
||||
_move_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {} |
||||
|
||||
static void |
||||
_line_to_nil (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {} |
||||
|
||||
static void |
||||
_conic_to_nil (hb_position_t control_x HB_UNUSED, hb_position_t control_y HB_UNUSED, |
||||
hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, |
||||
void *user_data HB_UNUSED) {} |
||||
static void |
||||
_cubic_to_nil (hb_position_t control1_x HB_UNUSED, hb_position_t control1_y HB_UNUSED, |
||||
hb_position_t control2_x HB_UNUSED, hb_position_t control2_y HB_UNUSED, |
||||
hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, |
||||
void *user_data HB_UNUSED) {} |
||||
|
||||
static void |
||||
_close_path_nil (void *user_data HB_UNUSED) {} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_create: |
||||
* |
||||
* Creates a new decompose callbacks object. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
hb_ot_glyph_decompose_funcs_t * |
||||
hb_ot_glyph_decompose_funcs_create () |
||||
{ |
||||
hb_ot_glyph_decompose_funcs_t *funcs; |
||||
if (unlikely (!(funcs = hb_object_create<hb_ot_glyph_decompose_funcs_t> ()))) |
||||
return const_cast<hb_ot_glyph_decompose_funcs_t *> (&Null (hb_ot_glyph_decompose_funcs_t)); |
||||
|
||||
funcs->move_to = (hb_ot_glyph_decompose_move_to_func_t) _move_to_nil; |
||||
funcs->line_to = (hb_ot_glyph_decompose_line_to_func_t) _line_to_nil; |
||||
funcs->conic_to = (hb_ot_glyph_decompose_conic_to_func_t) _conic_to_nil; |
||||
funcs->cubic_to = (hb_ot_glyph_decompose_cubic_to_func_t) _cubic_to_nil; |
||||
funcs->close_path = (hb_ot_glyph_decompose_close_path_func_t) _close_path_nil; |
||||
return funcs; |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_reference: |
||||
* @funcs: decompose functions |
||||
* |
||||
* Add to callbacks object refcount. |
||||
* |
||||
* Returns: The same object. |
||||
* Since: REPLACEME |
||||
**/ |
||||
hb_ot_glyph_decompose_funcs_t * |
||||
hb_ot_glyph_decompose_funcs_reference (hb_ot_glyph_decompose_funcs_t *funcs) |
||||
{ |
||||
return hb_object_reference (funcs); |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_destroy: |
||||
* @funcs: decompose functions |
||||
* |
||||
* Decreases refcount of callbacks object and deletes the object if it reaches |
||||
* to zero. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
void |
||||
hb_ot_glyph_decompose_funcs_destroy (hb_ot_glyph_decompose_funcs_t *funcs) |
||||
{ |
||||
if (!hb_object_destroy (funcs)) return; |
||||
|
||||
free (funcs); |
||||
} |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose: |
||||
* @font: a font object |
||||
* @glyph: a glyph id |
||||
* @funcs: decompose callbacks object |
||||
* @user_data: parameter you like be passed to the callbacks when are called |
||||
* |
||||
* Decomposes a glyph. |
||||
* |
||||
* Returns: Whether the font had the glyph and the operation completed successfully. |
||||
* Since: REPLACEME |
||||
**/ |
||||
hb_bool_t |
||||
hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph, |
||||
const hb_ot_glyph_decompose_funcs_t *funcs, |
||||
void *user_data) |
||||
{ |
||||
if (unlikely (!funcs || funcs == &Null (hb_ot_glyph_decompose_funcs_t) || |
||||
glyph >= font->face->get_num_glyphs ())) |
||||
return false; |
||||
|
||||
if (font->face->table.glyf->get_path (font, glyph, funcs, user_data)) return true; |
||||
#ifndef HB_NO_CFF |
||||
if (font->face->table.cff1->get_path (font, glyph, funcs, user_data)) return true; |
||||
if (font->face->table.cff2->get_path (font, glyph, funcs, user_data)) return true; |
||||
#endif |
||||
|
||||
return false; |
||||
} |
||||
|
||||
#endif |
@ -0,0 +1,92 @@ |
||||
/*
|
||||
* Copyright © 2019-2020 Ebrahim Byagowi |
||||
* |
||||
* This is part of HarfBuzz, a text shaping library. |
||||
* |
||||
* Permission is hereby granted, without written agreement and without |
||||
* license or royalty fees, to use, copy, modify, and distribute this |
||||
* software and its documentation for any purpose, provided that the |
||||
* above copyright notice and the following two paragraphs appear in |
||||
* all copies of this software. |
||||
* |
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
||||
* DAMAGE. |
||||
* |
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||
*/ |
||||
|
||||
#ifndef HB_OT_H_IN |
||||
#error "Include <hb-ot.h> instead." |
||||
#endif |
||||
|
||||
#ifndef HB_OT_GLYPH_H |
||||
#define HB_OT_GLYPH_H |
||||
|
||||
#include "hb.h" |
||||
|
||||
HB_BEGIN_DECLS |
||||
|
||||
typedef void (*hb_ot_glyph_decompose_move_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data); |
||||
typedef void (*hb_ot_glyph_decompose_line_to_func_t) (hb_position_t to_x, hb_position_t to_y, void *user_data); |
||||
typedef void (*hb_ot_glyph_decompose_conic_to_func_t) (hb_position_t control_x, hb_position_t control_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
void *user_data); |
||||
typedef void (*hb_ot_glyph_decompose_cubic_to_func_t) (hb_position_t control1_x, hb_position_t control1_y, |
||||
hb_position_t control2_x, hb_position_t control2_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
void *user_data); |
||||
typedef void (*hb_ot_glyph_decompose_close_path_func_t) (void *user_data); |
||||
|
||||
/**
|
||||
* hb_ot_glyph_decompose_funcs_t: |
||||
* |
||||
* Glyph decompose callbacks. |
||||
* |
||||
* Since: REPLACEME |
||||
**/ |
||||
typedef struct hb_ot_glyph_decompose_funcs_t hb_ot_glyph_decompose_funcs_t; |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_set_move_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_move_to_func_t move_to); |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_set_line_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_move_to_func_t line_to); |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_conic_to_func_t conic_to); |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_cubic_to_func_t cubic_to); |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (hb_ot_glyph_decompose_funcs_t *funcs, |
||||
hb_ot_glyph_decompose_close_path_func_t close_path); |
||||
|
||||
HB_EXTERN hb_ot_glyph_decompose_funcs_t * |
||||
hb_ot_glyph_decompose_funcs_create (void); |
||||
|
||||
HB_EXTERN hb_ot_glyph_decompose_funcs_t * |
||||
hb_ot_glyph_decompose_funcs_reference (hb_ot_glyph_decompose_funcs_t *funcs); |
||||
|
||||
HB_EXTERN void |
||||
hb_ot_glyph_decompose_funcs_destroy (hb_ot_glyph_decompose_funcs_t *funcs); |
||||
|
||||
HB_EXTERN hb_bool_t |
||||
hb_ot_glyph_decompose (hb_font_t *font, hb_codepoint_t glyph, |
||||
const hb_ot_glyph_decompose_funcs_t *funcs, |
||||
void *user_data); |
||||
|
||||
HB_END_DECLS |
||||
|
||||
#endif /* HB_OT_GLYPH_H */ |
@ -0,0 +1,45 @@ |
||||
/*
|
||||
* Copyright © 2020 Ebrahim Byagowi |
||||
* |
||||
* This is part of HarfBuzz, a text shaping library. |
||||
* |
||||
* Permission is hereby granted, without written agreement and without |
||||
* license or royalty fees, to use, copy, modify, and distribute this |
||||
* software and its documentation for any purpose, provided that the |
||||
* above copyright notice and the following two paragraphs appear in |
||||
* all copies of this software. |
||||
* |
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
||||
* DAMAGE. |
||||
* |
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||
* |
||||
* Red Hat Author(s): Behdad Esfahbod |
||||
* Google Author(s): Behdad Esfahbod |
||||
*/ |
||||
|
||||
#ifndef HB_OT_GLYPH_HH |
||||
#define HB_OT_GLYPH_HH |
||||
|
||||
#include "hb.hh" |
||||
|
||||
struct hb_ot_glyph_decompose_funcs_t |
||||
{ |
||||
hb_object_header_t header; |
||||
|
||||
hb_ot_glyph_decompose_move_to_func_t move_to; |
||||
hb_ot_glyph_decompose_line_to_func_t line_to; |
||||
hb_ot_glyph_decompose_conic_to_func_t conic_to; |
||||
hb_ot_glyph_decompose_cubic_to_func_t cubic_to; |
||||
hb_ot_glyph_decompose_close_path_func_t close_path; |
||||
}; |
||||
|
||||
|
||||
#endif /* HB_OT_GLYPH_HH */ |
@ -0,0 +1,143 @@ |
||||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi |
||||
* |
||||
* This is part of HarfBuzz, a text shaping library. |
||||
* |
||||
* Permission is hereby granted, without written agreement and without |
||||
* license or royalty fees, to use, copy, modify, and distribute this |
||||
* software and its documentation for any purpose, provided that the |
||||
* above copyright notice and the following two paragraphs appear in |
||||
* all copies of this software. |
||||
* |
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
||||
* DAMAGE. |
||||
* |
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||
*/ |
||||
|
||||
#include "hb-ot.h" |
||||
|
||||
#ifdef HB_NO_OPEN |
||||
#define hb_blob_create_from_file(x) hb_blob_get_empty () |
||||
#endif |
||||
|
||||
#include <stdlib.h> |
||||
#include <stdio.h> |
||||
#include <assert.h> |
||||
|
||||
struct user_data_t |
||||
{ |
||||
FILE *f; |
||||
hb_position_t ascender; |
||||
}; |
||||
|
||||
static void |
||||
move_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data) |
||||
{ |
||||
fprintf (user_data.f, "M%d,%d", to_x, user_data.ascender - to_y); |
||||
} |
||||
|
||||
static void |
||||
line_to (hb_position_t to_x, hb_position_t to_y, user_data_t &user_data) |
||||
{ |
||||
fprintf (user_data.f, "L%d,%d", to_x, user_data.ascender - to_y); |
||||
} |
||||
|
||||
static void |
||||
conic_to (hb_position_t control_x, hb_position_t control_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
user_data_t &user_data) |
||||
{ |
||||
fprintf (user_data.f, "Q%d,%d %d,%d", control_x, user_data.ascender - control_y, |
||||
to_x, user_data.ascender - to_y); |
||||
} |
||||
|
||||
static void |
||||
cubic_to (hb_position_t control1_x, hb_position_t control1_y, |
||||
hb_position_t control2_x, hb_position_t control2_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
user_data_t &user_data) |
||||
{ |
||||
fprintf (user_data.f, "C%d,%d %d,%d %d,%d", control1_x, user_data.ascender - control1_y, |
||||
control2_x, user_data.ascender - control2_y, |
||||
to_x, user_data.ascender - to_y); |
||||
} |
||||
|
||||
static void |
||||
close_path (user_data_t &user_data) |
||||
{ |
||||
fprintf (user_data.f, "Z"); |
||||
} |
||||
|
||||
int |
||||
main (int argc, char **argv) |
||||
{ |
||||
if (argc != 2) |
||||
{ |
||||
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); |
||||
exit (1); |
||||
} |
||||
|
||||
hb_blob_t *blob = hb_blob_create_from_file (argv[1]); |
||||
unsigned int num_faces = hb_face_count (blob); |
||||
if (num_faces == 0) |
||||
{ |
||||
fprintf (stderr, "error: The file (%s) was corrupted, empty or not found", argv[1]); |
||||
exit (1); |
||||
} |
||||
|
||||
hb_ot_glyph_decompose_funcs_t *funcs = hb_ot_glyph_decompose_funcs_create (); |
||||
hb_ot_glyph_decompose_funcs_set_move_to_func (funcs, (hb_ot_glyph_decompose_move_to_func_t) move_to); |
||||
hb_ot_glyph_decompose_funcs_set_line_to_func (funcs, (hb_ot_glyph_decompose_line_to_func_t) line_to); |
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func (funcs, (hb_ot_glyph_decompose_conic_to_func_t) conic_to); |
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (funcs, (hb_ot_glyph_decompose_cubic_to_func_t) cubic_to); |
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (funcs, (hb_ot_glyph_decompose_close_path_func_t) close_path); |
||||
|
||||
for (unsigned int face_index = 0; face_index < hb_face_count (blob); face_index++) |
||||
{ |
||||
hb_face_t *face = hb_face_create (blob, face_index); |
||||
hb_font_t *font = hb_font_create (face); |
||||
unsigned int glyph_count = hb_face_get_glyph_count (face); |
||||
for (unsigned int gid = 0; gid < glyph_count; ++gid) |
||||
{ |
||||
hb_font_extents_t font_extents; |
||||
hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents); |
||||
hb_glyph_extents_t extents = {0}; |
||||
if (!hb_font_get_glyph_extents (font, gid, &extents)) |
||||
{ |
||||
printf ("Skip gid: %d\n", gid); |
||||
continue; |
||||
} |
||||
|
||||
char name[100]; |
||||
sprintf (name, "%d.svg", gid); |
||||
FILE *f = fopen (name, "wb"); |
||||
fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\"" |
||||
" viewBox=\"%d %d %d %d\"><path d=\"", |
||||
extents.x_bearing, 0, |
||||
extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender); //-extents.height);
|
||||
user_data_t user_data; |
||||
user_data.ascender = font_extents.ascender; |
||||
user_data.f = f; |
||||
if (!hb_ot_glyph_decompose (font, gid, funcs, &user_data)) |
||||
printf ("Failed to decompose gid: %d\n", gid); |
||||
fprintf (f, "\"/></svg>"); |
||||
fclose (f); |
||||
} |
||||
hb_font_destroy (font); |
||||
hb_face_destroy (face); |
||||
} |
||||
|
||||
hb_ot_glyph_decompose_funcs_destroy (funcs); |
||||
|
||||
hb_blob_destroy (blob); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,223 @@ |
||||
/*
|
||||
* Copyright © 2020 Ebrahim Byagowi |
||||
* |
||||
* This is part of HarfBuzz, a text shaping library. |
||||
* |
||||
* Permission is hereby granted, without written agreement and without |
||||
* license or royalty fees, to use, copy, modify, and distribute this |
||||
* software and its documentation for any purpose, provided that the |
||||
* above copyright notice and the following two paragraphs appear in |
||||
* all copies of this software. |
||||
* |
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
||||
* DAMAGE. |
||||
* |
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||||
*/ |
||||
|
||||
#include "hb-test.h" |
||||
|
||||
#include <hb-ot.h> |
||||
|
||||
typedef struct user_data_t { |
||||
char *str; |
||||
unsigned size; |
||||
unsigned consumed; |
||||
} user_data_t; |
||||
|
||||
static void |
||||
move_to (hb_position_t to_x, hb_position_t to_y, user_data_t *user_data) |
||||
{ |
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed, |
||||
user_data->size - user_data->consumed, |
||||
"M%d,%d", to_x, to_y); |
||||
} |
||||
|
||||
static void |
||||
line_to (hb_position_t to_x, hb_position_t to_y, user_data_t *user_data) |
||||
{ |
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed, |
||||
user_data->size - user_data->consumed, |
||||
"L%d,%d", to_x, to_y); |
||||
} |
||||
|
||||
static void |
||||
conic_to (hb_position_t control_x, hb_position_t control_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
user_data_t *user_data) |
||||
{ |
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed, |
||||
user_data->size - user_data->consumed, |
||||
"Q%d,%d %d,%d", |
||||
control_x, control_y, |
||||
to_x, to_y); |
||||
} |
||||
|
||||
static void |
||||
cubic_to (hb_position_t control1_x, hb_position_t control1_y, |
||||
hb_position_t control2_x, hb_position_t control2_y, |
||||
hb_position_t to_x, hb_position_t to_y, |
||||
user_data_t *user_data) |
||||
{ |
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed, |
||||
user_data->size - user_data->consumed, |
||||
"C%d,%d %d,%d %d,%d", |
||||
control1_x, control1_y, |
||||
control2_x, control2_y, |
||||
to_x, to_y); |
||||
} |
||||
|
||||
static void |
||||
close_path (user_data_t *user_data) |
||||
{ |
||||
user_data->consumed += snprintf (user_data->str + user_data->consumed, |
||||
user_data->size - user_data->consumed, |
||||
"Z"); |
||||
} |
||||
|
||||
static hb_ot_glyph_decompose_funcs_t *funcs; |
||||
|
||||
static void |
||||
test_hb_ot_glyph_empty (void) |
||||
{ |
||||
g_assert (!hb_ot_glyph_decompose (hb_font_get_empty (), 3, funcs, NULL)); |
||||
} |
||||
|
||||
static void |
||||
test_hb_ot_glyph_glyf (void) |
||||
{ |
||||
hb_face_t *face = hb_test_open_font_file ("fonts/SourceSerifVariable-Roman-VVAR.abc.ttf"); |
||||
hb_font_t *font = hb_font_create (face); |
||||
hb_face_destroy (face); |
||||
|
||||
char str[1024] = {0}; |
||||
user_data_t user_data = { |
||||
.str = str, |
||||
.size = sizeof (str), |
||||
.consumed = 0 |
||||
}; |
||||
g_assert (!hb_ot_glyph_decompose (font, 4, funcs, &user_data)); |
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data)); |
||||
char expected[] = "M275,442L275,442Q232,442 198,420Q164,397 145,353Q126,309 126,245L126,245" |
||||
"Q126,182 147,139Q167,95 204,73Q240,50 287,50L287,50Q330,50 367,70" |
||||
"Q404,90 427,128L427,128L451,116Q431,54 384,21Q336,-13 266,-13L266,-13Q198,-13 148,18" |
||||
"Q97,48 70,104Q43,160 43,236L43,236Q43,314 76,371Q108,427 160,457Q212,487 272,487L272,487" |
||||
"Q316,487 354,470Q392,453 417,424Q442,395 448,358L448,358Q441,321 403,321L403,321" |
||||
"Q378,321 367,334Q355,347 350,366L350,366L325,454L371,417Q346,430 321,436Q296,442 275,442Z"; |
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); |
||||
|
||||
hb_variation_t var; |
||||
var.tag = HB_TAG ('w','g','h','t'); |
||||
var.value = 800; |
||||
hb_font_set_variations (font, &var, 1); |
||||
|
||||
char str2[1024] = {0}; |
||||
user_data_t user_data2 = { |
||||
.str = str2, |
||||
.size = sizeof (str2), |
||||
.consumed = 0 |
||||
}; |
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data2)); |
||||
char expected2[] = "M323,448L323,448Q297,448 271,430Q244,412 227,371" |
||||
"Q209,330 209,261L209,261Q209,204 226,166Q242,127 273,107Q303,86 344,86L344,86Q378,86 404,101" |
||||
"Q430,115 451,137L451,137L488,103Q458,42 404,13Q350,-16 279,-16L279,-16Q211,-16 153,13Q95,41 60,99" |
||||
"Q25,156 25,241L25,241Q25,323 62,382Q99,440 163,471Q226,501 303,501L303,501Q357,501 399,481" |
||||
"Q440,460 464,426Q488,392 492,352L492,352Q475,297 420,297L420,297Q390,297 366,320" |
||||
"Q342,342 339,401L339,401L333,469L411,427Q387,438 368,443Q348,448 323,448Z"; |
||||
g_assert_cmpmem (str2, user_data2.consumed, expected2, sizeof (expected2) - 1); |
||||
|
||||
hb_font_destroy (font); |
||||
} |
||||
|
||||
static void |
||||
test_hb_ot_glyph_cff1 (void) |
||||
{ |
||||
hb_face_t *face = hb_test_open_font_file ("fonts/cff1_seac.otf"); |
||||
hb_font_t *font = hb_font_create (face); |
||||
hb_face_destroy (face); |
||||
|
||||
char str[1024] = {0}; |
||||
user_data_t user_data = { |
||||
.str = str, |
||||
.size = sizeof (str), |
||||
.consumed = 0 |
||||
}; |
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data)); |
||||
char expected[] = "M203,367C227,440 248,512 268,588L272,588C293,512 314,440 338,367L369,267L172,267Z" |
||||
"M3,0L88,0L151,200L390,200L452,0L541,0L319,656L225,656Z" |
||||
"M300,653L342,694L201,861L143,806Z"; |
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); |
||||
|
||||
hb_font_destroy (font); |
||||
} |
||||
|
||||
static void |
||||
test_hb_ot_glyph_cff2 (void) |
||||
{ |
||||
hb_face_t *face = hb_test_open_font_file ("fonts/AdobeVFPrototype.abc.otf"); |
||||
hb_font_t *font = hb_font_create (face); |
||||
hb_face_destroy (face); |
||||
|
||||
char str[1024] = {0}; |
||||
user_data_t user_data = { |
||||
.str = str, |
||||
.size = sizeof (str), |
||||
.consumed = 0 |
||||
}; |
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data)); |
||||
char expected[] = "M275,442C303,442 337,435 371,417L325,454L350,366" |
||||
"C357,341 370,321 403,321C428,321 443,333 448,358" |
||||
"C435,432 361,487 272,487C153,487 43,393 43,236" |
||||
"C43,83 129,-13 266,-13C360,-13 424,33 451,116L427,128" |
||||
"C396,78 345,50 287,50C193,50 126,119 126,245C126,373 188,442 275,442Z"; |
||||
g_assert_cmpmem (str, user_data.consumed, expected, sizeof (expected) - 1); |
||||
|
||||
hb_variation_t var; |
||||
var.tag = HB_TAG ('w','g','h','t'); |
||||
var.value = 800; |
||||
hb_font_set_variations (font, &var, 1); |
||||
|
||||
char str2[1024] = {0}; |
||||
user_data_t user_data2 = { |
||||
.str = str2, |
||||
.size = sizeof (str2), |
||||
.consumed = 0 |
||||
}; |
||||
g_assert (hb_ot_glyph_decompose (font, 3, funcs, &user_data2)); |
||||
char expected2[] = "M323,448C356,448 380,441 411,427L333,469L339,401" |
||||
"C343,322 379,297 420,297C458,297 480,314 492,352" |
||||
"C486,433 412,501 303,501C148,501 25,406 25,241" |
||||
"C25,70 143,-16 279,-16C374,-16 447,22 488,103L451,137" |
||||
"C423,107 390,86 344,86C262,86 209,148 209,261C209,398 271,448 323,448Z"; |
||||
g_assert_cmpmem (str2, user_data2.consumed, expected2, sizeof (expected2) - 1); |
||||
|
||||
hb_font_destroy (font); |
||||
} |
||||
|
||||
int |
||||
main (int argc, char **argv) |
||||
{ |
||||
funcs = hb_ot_glyph_decompose_funcs_create (); |
||||
hb_ot_glyph_decompose_funcs_set_move_to_func (funcs, (hb_ot_glyph_decompose_move_to_func_t) move_to); |
||||
hb_ot_glyph_decompose_funcs_set_line_to_func (funcs, (hb_ot_glyph_decompose_line_to_func_t) line_to); |
||||
hb_ot_glyph_decompose_funcs_set_conic_to_func (funcs, (hb_ot_glyph_decompose_conic_to_func_t) conic_to); |
||||
hb_ot_glyph_decompose_funcs_set_cubic_to_func (funcs, (hb_ot_glyph_decompose_cubic_to_func_t) cubic_to); |
||||
hb_ot_glyph_decompose_funcs_set_close_path_func (funcs, (hb_ot_glyph_decompose_close_path_func_t) close_path); |
||||
|
||||
hb_test_init (&argc, &argv); |
||||
hb_test_add (test_hb_ot_glyph_empty); |
||||
hb_test_add (test_hb_ot_glyph_glyf); |
||||
hb_test_add (test_hb_ot_glyph_cff1); |
||||
hb_test_add (test_hb_ot_glyph_cff2); |
||||
unsigned result = hb_test_run (); |
||||
|
||||
hb_ot_glyph_decompose_funcs_destroy (funcs); |
||||
return result; |
||||
} |
Loading…
Reference in new issue