From ddac44db5df944bf40a828afa90236289aca421b Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 1 Mar 2022 21:04:22 +1030 Subject: [PATCH 1/2] On vector surfaces render color glyphs in the fallback resolution --- src/cairo-surface.c | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 46f39cb20..e380880d0 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -2641,7 +2641,9 @@ composite_one_color_glyph (cairo_surface_t *surface, const cairo_pattern_t *source, const cairo_clip_t *clip, cairo_glyph_t *glyph, - cairo_scaled_glyph_t *scaled_glyph) + cairo_scaled_glyph_t *scaled_glyph, + double x_scale, + double y_scale) { cairo_int_status_t status; cairo_image_surface_t *glyph_surface; @@ -2661,11 +2663,12 @@ composite_one_color_glyph (cairo_surface_t *surface, int x, y; /* round glyph locations to the nearest pixels */ /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ - x = _cairo_lround (glyph->x - glyph_surface->base.device_transform.x0); - y = _cairo_lround (glyph->y - glyph_surface->base.device_transform.y0); + x = _cairo_lround (glyph->x * x_scale - glyph_surface->base.device_transform.x0); + y = _cairo_lround (glyph->y * y_scale - glyph_surface->base.device_transform.y0); pattern = cairo_pattern_create_for_surface ((cairo_surface_t *)glyph_surface); cairo_matrix_init_translate (&matrix, - x, - y); + cairo_matrix_scale (&matrix, x_scale, y_scale); cairo_pattern_set_matrix (pattern, &matrix); if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR || !has_color) status = surface->backend->mask (surface, op, pattern, pattern, clip); @@ -2702,6 +2705,27 @@ composite_color_glyphs (cairo_surface_t *surface, int gp; cairo_scaled_glyph_t *glyph_cache[GLYPH_CACHE_SIZE]; cairo_color_t *foreground_color = NULL; + double x_scale = 1.0; + double y_scale = 1.0; + + if (surface->is_vector) { + cairo_font_face_t *font_face; + cairo_matrix_t font_matrix; + cairo_matrix_t ctm; + cairo_font_options_t font_options; + + x_scale = surface->x_fallback_resolution / surface->x_resolution; + y_scale = surface->y_fallback_resolution / surface->y_resolution; + font_face = cairo_scaled_font_get_font_face (scaled_font); + cairo_scaled_font_get_font_matrix (scaled_font, &font_matrix); + cairo_scaled_font_get_ctm (scaled_font, &ctm); + cairo_scaled_font_get_font_options (scaled_font, &font_options); + cairo_matrix_scale (&ctm, x_scale, y_scale); + scaled_font = cairo_scaled_font_create (font_face, + &font_matrix, + &ctm, + &font_options); + } if (source->type == CAIRO_PATTERN_TYPE_SOLID) foreground_color = &((cairo_solid_pattern_t *) source)->color; @@ -2763,7 +2787,8 @@ composite_color_glyphs (cairo_surface_t *surface, goto UNLOCK; status = composite_one_color_glyph (surface, op, source, clip, - &glyphs[gp], scaled_glyph); + &glyphs[gp], scaled_glyph, + x_scale, y_scale); if (unlikely (status && status != CAIRO_INT_STATUS_NOTHING_TO_DO)) goto UNLOCK; } @@ -2799,7 +2824,8 @@ composite_color_glyphs (cairo_surface_t *surface, } status = composite_one_color_glyph (surface, op, source, clip, - &glyphs[glyph_pos], scaled_glyph); + &glyphs[glyph_pos], scaled_glyph, + x_scale, y_scale); if (unlikely (status && status != CAIRO_INT_STATUS_NOTHING_TO_DO)) goto UNLOCK; } @@ -2810,6 +2836,9 @@ composite_color_glyphs (cairo_surface_t *surface, UNLOCK: _cairo_scaled_font_thaw_cache (scaled_font); + if (surface->is_vector) + cairo_scaled_font_destroy (scaled_font); + return status; } From 5018120af05c4d043cdc2ac59d556865be51a049 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Tue, 1 Mar 2022 21:43:32 +1030 Subject: [PATCH 2/2] Update ref images --- .gitlab-ci/ignore-script-argb32.txt | 1 - .../reference/ft-color-font.recording.ref.png | Bin 0 -> 1655 bytes test/reference/ft-color-font.script.xfail.png | Bin 1976 -> 2015 bytes .../user-font-color.recording.ref.png | Bin 0 -> 4903 bytes .../user-font-color.recording.xfail.png | Bin 3040 -> 0 bytes .../user-font-color.script.xfail.png | Bin 1969 -> 2189 bytes 6 files changed, 1 deletion(-) create mode 100644 test/reference/ft-color-font.recording.ref.png create mode 100644 test/reference/user-font-color.recording.ref.png delete mode 100644 test/reference/user-font-color.recording.xfail.png diff --git a/.gitlab-ci/ignore-script-argb32.txt b/.gitlab-ci/ignore-script-argb32.txt index 8ea8607c2..e78be546f 100644 --- a/.gitlab-ci/ignore-script-argb32.txt +++ b/.gitlab-ci/ignore-script-argb32.txt @@ -23,7 +23,6 @@ linear-gradient-reflect map-all-to-image map-bit-to-image map-to-image-fill -mesh-pattern negative-stride-image overlapping-glyphs paint-source-alpha diff --git a/test/reference/ft-color-font.recording.ref.png b/test/reference/ft-color-font.recording.ref.png new file mode 100644 index 0000000000000000000000000000000000000000..902a00c17f5b38b0d29f759708674653ecae18c8 GIT binary patch literal 1655 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 RwG;pV002ovPDHLkV1gv`;Vu9G delta 1944 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 z z)b8d*vvxS9v}Z6m(|<_7W0Zxo+zZgzHXu6X!J(A6({|=1`i%|L5BZ@Sk$tjse{5$(aNow;ox+*Hr?Vq2ooirxmai_l zSHUNwh3ks>;VFH1yA#{~r2|(tcXon^MmV>yFPkRUxFDTe5M5Uo2~i!`i%Peq^pK?c zW;I{)_<-2gHW}=InCN5opbgi}A#IP}_q|5>c#HY`2Js#${vEgfg;D>cGGBCF=PF!0 TGz+oUUjU#cR*)iNr_g@@FeXm07LG(hhm&Fu zlpHEZNdO~7+T;8|2%$v;!2}`+5JEyEFV4Jq^Zt47W@o!VI!N&wdCIS>GP7y*>or%J>t%u9E}|2u)1 zS4{x?dWPk)u}>Xm%ez@}*_OmE+`Z!e)pVv{!OZa~`)8n82_0uUiGdQeSw*w?&qS+_ zXz9>P17DUM^QqI$JiG@FEj21 zTzzw5tAwhxUTgF}{>?yWK-c`iGzE@Wr#>9dmn6#_adLpHMrl2^eKxiu8#sIjAyw7e zqYKTFYp?;(&d5n;(8Jj5dsqKC7d=v=iZL6R@!2aj@0z;#Neu zrofI?@oVgscjlMXp@sFoXs}{>08DRrcm?dc-2157qFQdl4jZ)|j)?2xB~$Ex#$d9M z>R8VNX0hZwTe6SdljAi=7TP9AhoPwSniP;L>`Wq!uz7f9dw}5X=MT;; zvU>^6DE`~Uml<&j{h$ovw&3i&J4r@~;%{3^w z$1L!6={sxlv1vU1jqAZ#?!XMRVQNM|Ui}d%H#zgSYF%v$tEg9)*l$xW@@6-@DO&YiQzJy&^`bS`c7)dc z`uE#M8J2L+oB?&K79Q64r9%|Y8%S}vG$p8g0aZWWlzg`S}t1$2&6XTi}t!}aVv6}Fse&p=(#K^Idwp|}9Wg|O(azhSU9&AcQx}))q$q{pwuXrhG)w-wpEZRf^fq2{Ycx zT_;s`2QtVUd8pc|m+UvifZsp9!9Z`hRa3n|^`@w+(}h$V^)c10nifT`i3>gEYE@c$ z8r%a1r9i^v3yecc9W;RxVbU_w^LjsaR3>VZ<=-wm3O8Rj{`N^&Mbe_5)U}>JO{mFg zc;`@g1MN5%t#UZx3DGm9L&5havl1Q33IU5?=}?awI2+Y)=*sOZ-`Pb0t+#dnrLgGd zVOt$nXiU%gO>ekgxpDh$Q%5sp^X9Z2uAiP?Q7~7i9h3jHetV(!d4pA`fA3qahmNqD zo^gX$nw8}aZf-HC@?9;#$X<-qbNwJ+5)v_F^qr^Gl-{WjG(iF{H*&!|esE9gG>_eR zzO5x@Dp}agdAn#UE8c6SDT?oD{Ne|ULF^=Vd5%P*!cyQ3hL!R|iHl$Ip>wIWU~aQ& zxcumIQg{qStKwHHaL#_nb+$nstp$97{rb?$2<}~-^6K0qLT1Q8_Hz#Z3((#kigImJocN+QkgRrWKZ9P^g#qg#4X@IvFWr`Yw%a$>+KZeRQb^ zjH9t@n&P|%$%JXuo46%hUFGNB4{%jPBvW*V!k||#R#AM^vx)S8R2nIoc!FE2=`e2^ zzcEqjj?l00DTt*RFM1TRkr4Ny%9U>qP8-B#A#Zx1kJBv9|F$)gF770DQjqJ_ zNKO}(MKzWcL$dvl5X6wduyKutC_H6JTBEQ%$E%@8{5DcErrH${A}#UP!v07+W=KihbAULA5nK8$wU)2xjRYNI)77AQGkH5%{!^G z#J|qnSwnFMosjLP3+K!`87