tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

12-quartz-named-destination.patch (6599B)


      1 # HG changeset patch
      2 # User Jonathan Kew <jkew@mozilla.com>
      3 # Date 1628081557 0
      4 #      Wed Aug 04 12:52:37 2021 +0000
      5 # Node ID 2635200eb5ec6f6eff1ecd0fad1ef029f0b994af
      6 # Parent  99c4916f4a924ede94aee9044fe3f753d2e2be2d
      7 Bug 1892913 - patch 14 - Add cairo-quartz-surface named-destination support from bug 1722300 patch 3.
      8 
      9 diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c
     10 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c
     11 +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c
     12 @@ -2192,24 +2192,13 @@ static cairo_status_t
     13 }
     14 
     15 static cairo_int_status_t
     16 -_cairo_quartz_surface_tag (void			       *abstract_surface,
     17 -			   cairo_bool_t                 begin,
     18 -			   const char                  *tag_name,
     19 -			   const char                  *attributes,
     20 -			   const cairo_pattern_t       *source,
     21 -			   const cairo_stroke_style_t  *style,
     22 -			   const cairo_matrix_t	       *ctm,
     23 -			   const cairo_matrix_t	       *ctm_inverse,
     24 -			   const cairo_clip_t	       *clip)
     25 +_cairo_quartz_surface_link (cairo_quartz_surface_t *surface,
     26 +                            cairo_bool_t            begin,
     27 +                            const char             *attributes)
     28 {
     29     cairo_link_attrs_t link_attrs;
     30     cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
     31     int i, num_rects;
     32 -    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
     33 -
     34 -    /* Currently the only tag we support is "Link" */
     35 -    if (strcmp (tag_name, "Link"))
     36 -        return CAIRO_INT_STATUS_UNSUPPORTED;
     37 
     38     /* We only process the 'begin' tag, and expect a rect attribute;
     39        using the extents of the drawing operations enclosed by the begin/end
     40 @@ -2223,11 +2212,24 @@ static cairo_int_status_t
     41 
     42     num_rects = _cairo_array_num_elements (&link_attrs.rects);
     43     if (num_rects > 0) {
     44 -        CFURLRef url = CFURLCreateWithBytes (NULL,
     45 -                                             (const UInt8 *) link_attrs.uri,
     46 -                                             strlen (link_attrs.uri),
     47 -                                             kCFStringEncodingUTF8,
     48 -                                             NULL);
     49 +        /* Create either a named destination or a URL, depending which is present
     50 +           in the link attributes. */
     51 +        CFURLRef url = NULL;
     52 +        CFStringRef name = NULL;
     53 +        if (link_attrs.uri && *link_attrs.uri)
     54 +            url = CFURLCreateWithBytes (NULL,
     55 +                                        (const UInt8 *) link_attrs.uri,
     56 +                                        strlen (link_attrs.uri),
     57 +                                        kCFStringEncodingUTF8,
     58 +                                        NULL);
     59 +        else if (link_attrs.dest && *link_attrs.dest)
     60 +            name = CFStringCreateWithBytes (kCFAllocatorDefault,
     61 +                                            (const UInt8 *) link_attrs.dest,
     62 +                                            strlen (link_attrs.dest),
     63 +                                            kCFStringEncodingUTF8,
     64 +                                            FALSE);
     65 +        else /* silently ignore link that doesn't have a usable target */
     66 +            goto cleanup;
     67 
     68         for (i = 0; i < num_rects; i++) {
     69             CGRect link_rect;
     70 @@ -2241,12 +2243,19 @@ static cairo_int_status_t
     71                             rectf.width,
     72                             rectf.height);
     73 
     74 -            CGPDFContextSetURLForRect (surface->cgContext, url, link_rect);
     75 +            if (url)
     76 +                CGPDFContextSetURLForRect (surface->cgContext, url, link_rect);
     77 +            else
     78 +                CGPDFContextSetDestinationForRect (surface->cgContext, name, link_rect);
     79         }
     80 
     81 -        CFRelease (url);
     82 +        if (url)
     83 +            CFRelease (url);
     84 +        else
     85 +            CFRelease (name);
     86     }
     87 
     88 +cleanup:
     89     _cairo_array_fini (&link_attrs.rects);
     90     free (link_attrs.dest);
     91     free (link_attrs.uri);
     92 @@ -2255,6 +2264,74 @@ static cairo_int_status_t
     93     return status;
     94 }
     95 
     96 +static cairo_int_status_t
     97 +_cairo_quartz_surface_dest (cairo_quartz_surface_t *surface,
     98 +                            cairo_bool_t            begin,
     99 +                            const char             *attributes)
    100 +{
    101 +    cairo_dest_attrs_t dest_attrs;
    102 +    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
    103 +    double x = 0, y = 0;
    104 +
    105 +    /* We only process the 'begin' tag, and expect 'x' and 'y' attributes. */
    106 +    if (!begin)
    107 +        return status;
    108 +
    109 +    status = _cairo_tag_parse_dest_attributes (attributes, &dest_attrs);
    110 +    if (unlikely (status))
    111 +	return status;
    112 +
    113 +    if (unlikely (!dest_attrs.name || !strlen (dest_attrs.name)))
    114 +        goto cleanup;
    115 +
    116 +    CFStringRef name = CFStringCreateWithBytes (kCFAllocatorDefault,
    117 +                                                (const UInt8 *) dest_attrs.name,
    118 +                                                strlen (dest_attrs.name),
    119 +                                                kCFStringEncodingUTF8,
    120 +                                                FALSE);
    121 +
    122 +    if (dest_attrs.x_valid)
    123 +        x = dest_attrs.x;
    124 +    if (dest_attrs.y_valid)
    125 +        y = dest_attrs.y;
    126 +
    127 +    CGPDFContextAddDestinationAtPoint (surface->cgContext,
    128 +                                       name,
    129 +                                       CGPointMake (x, surface->extents.height - y));
    130 +    CFRelease (name);
    131 +
    132 +cleanup:
    133 +    free (dest_attrs.name);
    134 +
    135 +    return status;
    136 +}
    137 +
    138 +static cairo_int_status_t
    139 +_cairo_quartz_surface_tag (void			       *abstract_surface,
    140 +			   cairo_bool_t                 begin,
    141 +			   const char                  *tag_name,
    142 +			   const char                  *attributes,
    143 +			   const cairo_pattern_t       *source,
    144 +			   const cairo_stroke_style_t  *style,
    145 +			   const cairo_matrix_t	       *ctm,
    146 +			   const cairo_matrix_t	       *ctm_inverse,
    147 +			   const cairo_clip_t	       *clip)
    148 +{
    149 +    cairo_link_attrs_t link_attrs;
    150 +    int i, num_rects;
    151 +    cairo_quartz_surface_t *surface = (cairo_quartz_surface_t *) abstract_surface;
    152 +
    153 +    /* Currently the only tags we support are CAIRO_TAG_LINK and CAIRO_TAG_DEST */
    154 +    if (!strcmp (tag_name, CAIRO_TAG_LINK))
    155 +        return _cairo_quartz_surface_link (surface, begin, attributes);
    156 +
    157 +    if (!strcmp (tag_name, CAIRO_TAG_DEST))
    158 +        return _cairo_quartz_surface_dest (surface, begin, attributes);
    159 +
    160 +    /* Unknown tag names are silently ignored here. */
    161 +    return CAIRO_INT_STATUS_SUCCESS;
    162 +}
    163 +
    164 // XXXtodo implement show_page; need to figure out how to handle begin/end
    165 
    166 static const cairo_surface_backend_t cairo_quartz_surface_backend = {