win32: add synthetic font subsetting support

This commit is contained in:
Adrian Johnson 2010-11-23 00:13:56 +10:30
parent 7f0029c31e
commit 1effa1e823
4 changed files with 95 additions and 0 deletions

View file

@ -714,6 +714,29 @@ _cairo_truetype_read_font_name (cairo_scaled_font_t *scaled_font,
char **ps_name,
char **font_name);
/**
* _cairo_truetype_get_style:
* @scaled_font: the #cairo_scaled_font_t
* @weight: returns the font weight from the OS/2 table
* @bold: returns true if font is bold
* @italic: returns true if font is italic
*
* If the font is a truetype/opentype font with an OS/2 table, get the
* weight, bold, and italic data from the OS/2 table. The weight
* values have the same meaning as the lfWeight field of the Windows
* LOGFONT structure. Refer to the TrueType Specification for
* definition of the weight values.
*
* Return value: %CAIRO_STATUS_SUCCESS if successful,
* %CAIRO_INT_STATUS_UNSUPPORTED if the font is not TrueType/OpenType
* or the OS/2 table is not present.
**/
cairo_private cairo_int_status_t
_cairo_truetype_get_style (cairo_scaled_font_t *scaled_font,
int *weight,
cairo_bool_t *bold,
cairo_bool_t *italic);
#endif /* CAIRO_HAS_FONT_SUBSET */
#endif /* CAIRO_SCALED_FONT_SUBSETS_PRIVATE_H */

View file

@ -64,6 +64,7 @@
#define TT_TAG_loca MAKE_TT_TAG('l','o','c','a')
#define TT_TAG_maxp MAKE_TT_TAG('m','a','x','p')
#define TT_TAG_name MAKE_TT_TAG('n','a','m','e')
#define TT_TAG_OS2 MAKE_TT_TAG('O','S','/','2')
#define TT_TAG_post MAKE_TT_TAG('p','o','s','t')
#define TT_TAG_prep MAKE_TT_TAG('p','r','e','p')
@ -174,6 +175,18 @@ typedef struct _tt_name {
} tt_name_t;
/* bitmask for fsSelection field */
#define TT_FS_SELECTION_ITALIC 1
#define TT_FS_SELECTION_BOLD 32
/* _unused fields are defined in TT spec but not used by cairo */
typedef struct _tt_os2 {
uint16_t _unused1[2];
uint16_t usWeightClass;
uint16_t _unused2[28];
uint16_t fsSelection;
uint16_t _unused3[11];
} tt_os2_t;
/* composite_glyph_t flags */
#define TT_ARG_1_AND_2_ARE_WORDS 0x0001

View file

@ -1502,4 +1502,36 @@ fail:
return status;
}
cairo_int_status_t
_cairo_truetype_get_style (cairo_scaled_font_t *scaled_font,
int *weight,
cairo_bool_t *bold,
cairo_bool_t *italic)
{
cairo_status_t status;
const cairo_scaled_font_backend_t *backend;
tt_os2_t os2;
unsigned long size;
uint16_t selection;
backend = scaled_font->backend;
if (!backend->load_truetype_table)
return CAIRO_INT_STATUS_UNSUPPORTED;
size = sizeof (os2);
status = backend->load_truetype_table (scaled_font,
TT_TAG_OS2, 0,
(unsigned char *) &os2,
&size);
if (status)
return status;
*weight = be16_to_cpu (os2.usWeightClass);
selection = be16_to_cpu (os2.fsSelection);
*bold = (selection & TT_FS_SELECTION_BOLD) ? TRUE : FALSE;
*italic = (selection & TT_FS_SELECTION_ITALIC) ? TRUE : FALSE;
return CAIRO_STATUS_SUCCESS;
}
#endif /* CAIRO_HAS_FONT_SUBSET */

View file

@ -46,6 +46,7 @@
#include "cairo-win32-private.h"
#include "cairo-error-private.h"
#include "cairo-scaled-font-subsets-private.h"
#include <wchar.h>
@ -1623,6 +1624,31 @@ exit1:
return status;
}
static cairo_bool_t
_cairo_win32_scaled_font_is_synthetic (void *abstract_font)
{
cairo_win32_scaled_font_t *scaled_font = abstract_font;
cairo_status_t status;
int weight;
cairo_bool_t bold;
cairo_bool_t italic;
status = _cairo_truetype_get_style (&scaled_font->base,
&weight,
&bold,
&italic);
/* If this doesn't work assume it is not synthetic to avoid
* unneccessary subsetting fallbacks. */
if (status != CAIRO_STATUS_SUCCESS)
return FALSE;
if (scaled_font->logfont.lfWeight != weight ||
scaled_font->logfont.lfItalic != italic)
return TRUE;
return FALSE;
}
static cairo_status_t
_cairo_win32_scaled_font_init_glyph_surface (cairo_win32_scaled_font_t *scaled_font,
cairo_scaled_glyph_t *scaled_glyph)
@ -1871,6 +1897,7 @@ const cairo_scaled_font_backend_t _cairo_win32_scaled_font_backend = {
_cairo_win32_scaled_font_show_glyphs,
_cairo_win32_scaled_font_load_truetype_table,
_cairo_win32_scaled_font_index_to_ucs4,
_cairo_win32_scaled_font_is_synthetic
};
/* #cairo_win32_font_face_t */