[cairo-commit] src/cairo-atsui-font.c

Behdad Esfahbod behdad at kemper.freedesktop.org
Sat Dec 23 12:34:21 PST 2006


 src/cairo-atsui-font.c |  154 ++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 115 insertions(+), 39 deletions(-)

New commits:
diff-tree 261d6b805c77dacb27d29d054e48ed548f1fbcc5 (from ee01bd9e173b6d36d6255553d0fcf1b54027dffd)
Author: Brian Ewins <Brian.Ewins at gmail.com>
Date:   Sat Dec 23 15:33:52 2006 -0500

    [ATSUI] Compute glyph extents from the bounding boxes of their paths (#9350)

diff --git a/src/cairo-atsui-font.c b/src/cairo-atsui-font.c
index eaca0a7..75530d3 100644
--- a/src/cairo-atsui-font.c
+++ b/src/cairo-atsui-font.c
@@ -181,12 +181,10 @@ _cairo_atsui_font_set_metrics (cairo_ats
     atsFont = FMGetATSFontRefFromFont(font->fontID);
 
     if (atsFont) {
-        err =
-            ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault,
-                                        &metrics);
+        err = ATSFontGetHorizontalMetrics(atsFont, kATSOptionFlagsDefault, &metrics);
 
         if (err == noErr) {
-	    	cairo_font_extents_t extents;
+	    cairo_font_extents_t extents;
 
             extents.ascent = metrics.ascent;
             extents.descent = -metrics.descent;
@@ -196,7 +194,7 @@ _cairo_atsui_font_set_metrics (cairo_ats
             /* The FT backend doesn't handle max_y_advance either, so we'll ignore it for now. */
             extents.max_y_advance = 0.0;
 
-	    	_cairo_scaled_font_set_metrics (&font->base, &extents);
+	    _cairo_scaled_font_set_metrics (&font->base, &extents);
 
             return CAIRO_STATUS_SUCCESS;
         }
@@ -356,44 +354,122 @@ _cairo_atsui_font_fini(void *abstract_fo
         ATSUDisposeStyle(font->unscaled_style);
 }
 
+static
+OSStatus _move_to_for_metrics (const Float32Point *point, void *callback_data)
+{
+    CGMutablePathRef path = callback_data;
+
+    CGPathMoveToPoint (path, &CGAffineTransformIdentity,
+			   point->x, point->y);
+    return noErr;
+}
+
+static
+OSStatus _line_to_for_metrics(const Float32Point *point, void *callback_data)
+{
+    CGMutablePathRef path = callback_data;
+
+    CGPathAddLineToPoint (path, &CGAffineTransformIdentity,
+			   point->x, point->y);
+    return noErr;
+}
+
+static
+OSStatus _curve_to_for_metrics (const Float32Point *point1,
+				const Float32Point *point2,
+				const Float32Point *point3,
+				void *callback_data)
+{
+    CGMutablePathRef path = callback_data;
+
+    CGPathAddCurveToPoint (path, &CGAffineTransformIdentity,
+			   point1->x, point1->y,
+			   point2->x, point2->y,
+			   point3->x, point3->y);
+    return noErr;
+}
+
+static
+OSStatus _close_path_for_metrics(void *callback_data)
+{
+    CGMutablePathRef path = callback_data;
+
+    CGPathCloseSubpath (path);
+    return noErr;
+}
+
 static cairo_status_t
-_cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *font,
+_cairo_atsui_font_init_glyph_metrics (cairo_atsui_font_t *scaled_font,
 				      cairo_scaled_glyph_t *scaled_glyph)
 {
-   cairo_text_extents_t extents;
-   OSStatus err;
-   GlyphID theGlyph = _cairo_scaled_glyph_index (scaled_glyph);
-   ATSGlyphScreenMetrics metricsH, metricsV;
-   ATSUStyle style,style1;
-   ATSUVerticalCharacterType verticalType = kATSUStronglyVertical;
-   const ATSUAttributeTag theTag[] = { kATSUVerticalCharacterTag };
-   const ByteCount theSizes[] = { sizeof(verticalType) };
-   ATSUAttributeValuePtr theValues[] = { &verticalType };
-   double xscale;
-   double yscale;
-
-   _cairo_matrix_compute_scale_factors(&font->base.scale, &xscale, &yscale, 1);
-
-   ATSUCreateAndCopyStyle(font->style, &style);
-
-   err = ATSUGlyphGetScreenMetrics(style,
-				   1, &theGlyph, 0, false, false, &metricsH);
-   err = ATSUSetAttributes(style, 1, theTag, theSizes, theValues);
-   err = ATSUGlyphGetScreenMetrics(style,
-				   1, &theGlyph, 0, false, false, &metricsV);
-
-   extents.width = metricsH.width/xscale;
-   extents.height = metricsH.height/yscale;
-   extents.x_bearing = metricsH.sideBearing.x/xscale;
-   extents.y_bearing = metricsV.sideBearing.y/yscale - extents.height;
-   extents.x_advance = metricsH.deviceAdvance.x/xscale;
-   extents.y_advance = 0;
-
-  _cairo_scaled_glyph_set_metrics (scaled_glyph,
-				   &font->base,
-				   &extents);
+    cairo_text_extents_t extents;
+    OSStatus err, callback_err;
+    ATSGlyphScreenMetrics metricsH;
+    static ATSCubicMoveToUPP moveProc = NULL;
+    static ATSCubicLineToUPP lineProc = NULL;
+    static ATSCubicCurveToUPP curveProc = NULL;
+    static ATSCubicClosePathUPP closePathProc = NULL;
+    CGMutablePathRef path;
+    GlyphID theGlyph = _cairo_scaled_glyph_index (scaled_glyph);
+    double xscale, yscale;
+    CGRect rect;
 
-  return CAIRO_STATUS_SUCCESS;
+    /* We calculate the advance from the screen metrics. We
+     * could probably take this from the glyph path.
+     */
+    err = ATSUGlyphGetScreenMetrics (scaled_font->style,
+				     1, &theGlyph, 0, false,
+				     false, &metricsH);
+    if (err != noErr)
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+
+    /* Scale down to font units.*/
+    _cairo_matrix_compute_scale_factors (&scaled_font->base.scale,
+					 &xscale, &yscale, 1);
+    xscale = 1.0/xscale;
+    yscale = 1.0/yscale;
+
+    extents.x_advance = metricsH.deviceAdvance.x * xscale;
+    extents.y_advance = 0;
+
+    if (moveProc == NULL) {
+        moveProc = NewATSCubicMoveToUPP (_move_to_for_metrics);
+        lineProc = NewATSCubicLineToUPP (_line_to_for_metrics);
+        curveProc = NewATSCubicCurveToUPP (_curve_to_for_metrics);
+        closePathProc = NewATSCubicClosePathUPP (_close_path_for_metrics);
+    }
+
+    path = CGPathCreateMutable ();
+
+    /* The callback error contains any error our functions returned.
+     * Its only meaningful if err != noErr, and we don't currently
+     * use it for anything.
+     */
+    err = ATSUGlyphGetCubicPaths (scaled_font->style, theGlyph,
+				  moveProc, lineProc, curveProc, closePathProc,
+				  (void *)path, &callback_err);
+
+    if (err != noErr) {
+	/* This could potentially happen for bitmap fonts, where
+	 * no paths are available.
+	 */
+	CGPathRelease (path);
+	return CAIRO_INT_STATUS_UNSUPPORTED;
+    }
+
+    rect = CGPathGetBoundingBox (path);
+
+    extents.x_bearing = rect.origin.x * xscale;
+    extents.y_bearing = rect.origin.y * yscale;
+    extents.width = rect.size.width * xscale;
+    extents.height = rect.size.height * yscale;
+
+    _cairo_scaled_glyph_set_metrics (scaled_glyph,
+				     &scaled_font->base,
+				     &extents);
+    CGPathRelease (path);
+
+    return CAIRO_STATUS_SUCCESS;
 }
 
 static OSStatus


More information about the cairo-commit mailing list