summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Johnson <ajohnson@redneon.com>2010-11-23 00:13:56 +1030
committerAdrian Johnson <ajohnson@redneon.com>2010-11-23 00:13:56 +1030
commit1effa1e8230e16c59ce5f42692095f7fb6622c99 (patch)
tree633169ba46c4aa61f366823cf395940bda06c516
parent7f0029c31e15dfd34f57bdeca18f27e9e7b8f9aa (diff)
win32: add synthetic font subsetting support
-rw-r--r--src/cairo-scaled-font-subsets-private.h23
-rw-r--r--src/cairo-truetype-subset-private.h13
-rw-r--r--src/cairo-truetype-subset.c32
-rw-r--r--src/cairo-win32-font.c27
4 files changed, 95 insertions, 0 deletions
diff --git a/src/cairo-scaled-font-subsets-private.h b/src/cairo-scaled-font-subsets-private.h
index 45fded9d1..527739442 100644
--- a/src/cairo-scaled-font-subsets-private.h
+++ b/src/cairo-scaled-font-subsets-private.h
@@ -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 */
diff --git a/src/cairo-truetype-subset-private.h b/src/cairo-truetype-subset-private.h
index aed60d028..dc9573216 100644
--- a/src/cairo-truetype-subset-private.h
+++ b/src/cairo-truetype-subset-private.h
@@ -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
diff --git a/src/cairo-truetype-subset.c b/src/cairo-truetype-subset.c
index 7777996a8..a041b1624 100644
--- a/src/cairo-truetype-subset.c
+++ b/src/cairo-truetype-subset.c
@@ -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 */
diff --git a/src/cairo-win32-font.c b/src/cairo-win32-font.c
index 7af252b03..fcd7b5601 100644
--- a/src/cairo-win32-font.c
+++ b/src/cairo-win32-font.c
@@ -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 */