Changeset 227055 in webkit


Ignore:
Timestamp:
Jan 17, 2018 1:35:58 AM (6 years ago)
Author:
zandobersek@gmail.com
Message:

[Cairo] Move prepareForFilling(), prepareForStroking() code to CairoOperations
https://bugs.webkit.org/show_bug.cgi?id=181721

Reviewed by Carlos Garcia Campos.

Move the prepareForFilling() and prepareForStroking() code off of the
PlatformContextCairo class and into static functions inside the
CairoOperations implementation files. The original methods weren't
called from any place other than the Cairo operations, and they only
operated with the cairo_t object that's stored in and retrievable from
the PlatformContextCairo object.

No new tests -- no change in behavior.

  • platform/graphics/cairo/CairoOperations.cpp:

(WebCore::Cairo::reduceSourceByAlpha):
(WebCore::Cairo::prepareCairoContextSource):
(WebCore::Cairo::clipForPatternFilling):
(WebCore::Cairo::prepareForFilling):
(WebCore::Cairo::prepareForStroking):
(WebCore::Cairo::drawPathShadow):
(WebCore::Cairo::fillCurrentCairoPath):
(WebCore::Cairo::strokeRect):
(WebCore::Cairo::strokePath):
(WebCore::Cairo::drawGlyphs):

  • platform/graphics/cairo/PlatformContextCairo.cpp:

(WebCore::reduceSourceByAlpha): Deleted.
(WebCore::prepareCairoContextSource): Deleted.
(WebCore::PlatformContextCairo::prepareForFilling): Deleted.
(WebCore::PlatformContextCairo::prepareForStroking): Deleted.
(WebCore::PlatformContextCairo::clipForPatternFilling): Deleted.

  • platform/graphics/cairo/PlatformContextCairo.h:
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r227051 r227055  
     12018-01-17  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [Cairo] Move prepareForFilling(), prepareForStroking() code to CairoOperations
     4        https://bugs.webkit.org/show_bug.cgi?id=181721
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Move the prepareForFilling() and prepareForStroking() code off of the
     9        PlatformContextCairo class and into static functions inside the
     10        CairoOperations implementation files. The original methods weren't
     11        called from any place other than the Cairo operations, and they only
     12        operated with the cairo_t object that's stored in and retrievable from
     13        the PlatformContextCairo object.
     14
     15        No new tests -- no change in behavior.
     16
     17        * platform/graphics/cairo/CairoOperations.cpp:
     18        (WebCore::Cairo::reduceSourceByAlpha):
     19        (WebCore::Cairo::prepareCairoContextSource):
     20        (WebCore::Cairo::clipForPatternFilling):
     21        (WebCore::Cairo::prepareForFilling):
     22        (WebCore::Cairo::prepareForStroking):
     23        (WebCore::Cairo::drawPathShadow):
     24        (WebCore::Cairo::fillCurrentCairoPath):
     25        (WebCore::Cairo::strokeRect):
     26        (WebCore::Cairo::strokePath):
     27        (WebCore::Cairo::drawGlyphs):
     28        * platform/graphics/cairo/PlatformContextCairo.cpp:
     29        (WebCore::reduceSourceByAlpha): Deleted.
     30        (WebCore::prepareCairoContextSource): Deleted.
     31        (WebCore::PlatformContextCairo::prepareForFilling): Deleted.
     32        (WebCore::PlatformContextCairo::prepareForStroking): Deleted.
     33        (WebCore::PlatformContextCairo::clipForPatternFilling): Deleted.
     34        * platform/graphics/cairo/PlatformContextCairo.h:
     35
    1362018-01-17  Zan Dobersek  <zdobersek@igalia.com>
    237
  • trunk/Source/WebCore/platform/graphics/cairo/CairoOperations.cpp

    r227051 r227055  
    5151namespace Cairo {
    5252
     53enum PatternAdjustment { NoAdjustment, AdjustPatternForGlobalAlpha };
     54enum AlphaPreservation { DoNotPreserveAlpha, PreserveAlpha };
     55
     56static void reduceSourceByAlpha(cairo_t* cr, float alpha)
     57{
     58    if (alpha >= 1)
     59        return;
     60    cairo_push_group(cr);
     61    cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
     62    cairo_paint_with_alpha(cr, alpha);
     63    cairo_pop_group_to_source(cr);
     64}
     65
     66static void prepareCairoContextSource(cairo_t* cr, cairo_pattern_t* pattern, cairo_pattern_t* gradient, const Color& color, float globalAlpha)
     67{
     68    if (pattern) {
     69        // Pattern source
     70        cairo_set_source(cr, pattern);
     71        reduceSourceByAlpha(cr, globalAlpha);
     72    } else if (gradient) {
     73        // Gradient source
     74        cairo_set_source(cr, gradient);
     75    } else {
     76        // Solid color source
     77        if (globalAlpha < 1)
     78            setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha));
     79        else
     80            setSourceRGBAFromColor(cr, color);
     81    }
     82}
     83
     84static void clipForPatternFilling(cairo_t* cr, const FloatSize& patternSize, const AffineTransform& patternTransform, bool repeatX, bool repeatY)
     85{
     86    // Hold current cairo path in a variable for restoring it after configuring the pattern clip rectangle.
     87    auto currentPath = cairo_copy_path(cr);
     88    cairo_new_path(cr);
     89
     90    // Initialize clipping extent from current cairo clip extents, then shrink if needed according to pattern.
     91    // Inspired by GraphicsContextQt::drawRepeatPattern.
     92    double x1, y1, x2, y2;
     93    cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
     94    FloatRect clipRect(x1, y1, x2 - x1, y2 - y1);
     95
     96    FloatRect patternRect = patternTransform.mapRect(FloatRect(FloatPoint(), patternSize));
     97
     98    if (!repeatX) {
     99        clipRect.setX(patternRect.x());
     100        clipRect.setWidth(patternRect.width());
     101    }
     102    if (!repeatY) {
     103        clipRect.setY(patternRect.y());
     104        clipRect.setHeight(patternRect.height());
     105    }
     106    if (!repeatX || !repeatY) {
     107        cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());
     108        cairo_clip(cr);
     109    }
     110
     111    // Restoring cairo path.
     112    cairo_append_path(cr, currentPath);
     113    cairo_path_destroy(currentPath);
     114}
     115
     116static void prepareForFilling(cairo_t* cr, const Cairo::FillSource& fillSource, float globalAlpha, PatternAdjustment patternAdjustment)
     117{
     118    cairo_set_fill_rule(cr, fillSource.fillRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
     119
     120    bool adjustForAlpha = patternAdjustment == AdjustPatternForGlobalAlpha;
     121
     122    auto* gradient = fillSource.gradient.base.get();
     123    if (adjustForAlpha && fillSource.gradient.alphaAdjusted)
     124        gradient = fillSource.gradient.alphaAdjusted.get();
     125
     126    prepareCairoContextSource(cr, fillSource.pattern.object.get(), gradient,
     127        fillSource.color, adjustForAlpha ? globalAlpha : 1);
     128
     129    if (fillSource.pattern.object) {
     130        clipForPatternFilling(cr, fillSource.pattern.size, fillSource.pattern.transform,
     131            fillSource.pattern.repeatX, fillSource.pattern.repeatY);
     132    }
     133}
     134
     135void prepareForStroking(cairo_t* cr, const Cairo::StrokeSource& strokeSource, float globalAlpha, AlphaPreservation alphaPreservation)
     136{
     137    bool preserveAlpha = alphaPreservation == PreserveAlpha;
     138
     139    auto* gradient = strokeSource.gradient.base.get();
     140    if (preserveAlpha && strokeSource.gradient.alphaAdjusted)
     141        gradient = strokeSource.gradient.alphaAdjusted.get();
     142
     143    prepareCairoContextSource(cr, strokeSource.pattern.get(), gradient,
     144        strokeSource.color, preserveAlpha ? globalAlpha : 1);
     145}
     146
    53147static inline void fillRectWithColor(cairo_t* cr, const FloatRect& rect, const Color& color)
    54148{
     
    107201        cairo_save(cairoShadowContext);
    108202        cairo_append_path(cairoShadowContext, path.get());
    109         shadowContext->platformContext()->prepareForFilling(fillSource, PlatformContextCairo::NoAdjustment);
     203        prepareForFilling(cairoShadowContext, fillSource, shadowContext->platformContext()->globalAlpha(), NoAdjustment);
    110204        cairo_fill(cairoShadowContext);
    111205        cairo_restore(cairoShadowContext);
     
    114208    if (drawingStyle & Stroke) {
    115209        cairo_append_path(cairoShadowContext, path.get());
    116         shadowContext->platformContext()->prepareForStroking(strokeSource, PlatformContextCairo::DoNotPreserveAlpha);
     210        prepareForStroking(cairoShadowContext, strokeSource, shadowContext->platformContext()->globalAlpha(), DoNotPreserveAlpha);
    117211        cairo_stroke(cairoShadowContext);
    118212    }
     
    132226    cairo_save(cr);
    133227
    134     platformContext.prepareForFilling(fillSource, PlatformContextCairo::AdjustPatternForGlobalAlpha);
     228    prepareForFilling(cr, fillSource, platformContext.globalAlpha(), AdjustPatternForGlobalAlpha);
    135229    cairo_fill(cr);
    136230
     
    627721    cairo_set_line_width(cr, lineWidth);
    628722    drawPathShadow(platformContext, { }, strokeSource, shadowState, targetContext, Stroke);
    629     platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
     723    prepareForStroking(cr, strokeSource, platformContext.globalAlpha(), PreserveAlpha);
    630724    cairo_stroke(cr);
    631725
     
    639733    setPathOnCairoContext(cr, path.platformPath()->context());
    640734    drawPathShadow(platformContext, { }, strokeSource, shadowState, targetContext, Stroke);
    641     platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
     735    prepareForStroking(cr, strokeSource, platformContext.globalAlpha(), PreserveAlpha);
    642736    cairo_stroke(cr);
    643737}
     
    662756
    663757    if (textDrawingMode & TextModeFill) {
    664         platformContext.prepareForFilling(fillSource, PlatformContextCairo::AdjustPatternForGlobalAlpha);
     758        prepareForFilling(cr, fillSource, platformContext.globalAlpha(), AdjustPatternForGlobalAlpha);
    665759        drawGlyphsToContext(cr, scaledFont, syntheticBoldOffset, glyphs);
    666760    }
     
    671765    //  See https://bugs.webkit.org/show_bug.cgi?id=33759.
    672766    if (textDrawingMode & TextModeStroke && strokeThickness < 2 * xOffset) {
    673         platformContext.prepareForStroking(strokeSource, PlatformContextCairo::PreserveAlpha);
     767        prepareForStroking(cr, strokeSource, platformContext.globalAlpha(), PreserveAlpha);
    674768        cairo_set_line_width(cr, strokeThickness);
    675769
  • trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.cpp

    r227051 r227055  
    255255}
    256256
    257 static inline void reduceSourceByAlpha(cairo_t* cr, float alpha)
    258 {
    259     if (alpha >= 1)
    260         return;
    261     cairo_push_group(cr);
    262     cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
    263     cairo_paint_with_alpha(cr, alpha);
    264     cairo_pop_group_to_source(cr);
    265 }
    266 
    267 static void prepareCairoContextSource(cairo_t* cr, cairo_pattern_t* pattern, cairo_pattern_t* gradient, const Color& color, float globalAlpha)
    268 {
    269     if (pattern) {
    270         // Pattern source
    271         cairo_set_source(cr, pattern);
    272         reduceSourceByAlpha(cr, globalAlpha);
    273     } else if (gradient) {
    274         // Gradient source
    275         cairo_set_source(cr, gradient);
    276     } else {
    277         // Solid color source
    278         if (globalAlpha < 1)
    279             setSourceRGBAFromColor(cr, colorWithOverrideAlpha(color.rgb(), color.alpha() / 255.f * globalAlpha));
    280         else
    281             setSourceRGBAFromColor(cr, color);
    282     }
    283 }
    284 
    285 void PlatformContextCairo::prepareForFilling(const Cairo::FillSource& fillSource, PatternAdjustment patternAdjustment)
    286 {
    287     cairo_set_fill_rule(m_cr.get(), fillSource.fillRule == RULE_EVENODD ? CAIRO_FILL_RULE_EVEN_ODD : CAIRO_FILL_RULE_WINDING);
    288 
    289     bool adjustForAlpha = patternAdjustment == AdjustPatternForGlobalAlpha;
    290 
    291     auto* gradient = fillSource.gradient.base.get();
    292     if (adjustForAlpha && fillSource.gradient.alphaAdjusted)
    293         gradient = fillSource.gradient.alphaAdjusted.get();
    294 
    295     prepareCairoContextSource(m_cr.get(), fillSource.pattern.object.get(), gradient,
    296         fillSource.color, adjustForAlpha ? globalAlpha() : 1);
    297 
    298     if (fillSource.pattern.object) {
    299         clipForPatternFilling(fillSource.pattern.size, fillSource.pattern.transform,
    300             fillSource.pattern.repeatX, fillSource.pattern.repeatY);
    301     }
    302 }
    303 
    304 void PlatformContextCairo::prepareForStroking(const Cairo::StrokeSource& strokeSource, AlphaPreservation alphaPreservation)
    305 {
    306     bool preserveAlpha = alphaPreservation == PreserveAlpha;
    307 
    308     auto* gradient = strokeSource.gradient.base.get();
    309     if (preserveAlpha && strokeSource.gradient.alphaAdjusted)
    310         gradient = strokeSource.gradient.alphaAdjusted.get();
    311 
    312     prepareCairoContextSource(m_cr.get(), strokeSource.pattern.get(), gradient,
    313         strokeSource.color, preserveAlpha ? globalAlpha() : 1);
    314 }
    315 
    316 void PlatformContextCairo::clipForPatternFilling(const FloatSize& patternSize, const AffineTransform& patternTransform, bool repeatX, bool repeatY)
    317 {
    318     // Hold current cairo path in a variable for restoring it after configuring the pattern clip rectangle.
    319     auto currentPath = cairo_copy_path(m_cr.get());
    320     cairo_new_path(m_cr.get());
    321 
    322     // Initialize clipping extent from current cairo clip extents, then shrink if needed according to pattern.
    323     // Inspired by GraphicsContextQt::drawRepeatPattern.
    324     double x1, y1, x2, y2;
    325     cairo_clip_extents(m_cr.get(), &x1, &y1, &x2, &y2);
    326     FloatRect clipRect(x1, y1, x2 - x1, y2 - y1);
    327 
    328     FloatRect patternRect = patternTransform.mapRect(FloatRect(FloatPoint(), patternSize));
    329 
    330     if (!repeatX) {
    331         clipRect.setX(patternRect.x());
    332         clipRect.setWidth(patternRect.width());
    333     }
    334     if (!repeatY) {
    335         clipRect.setY(patternRect.y());
    336         clipRect.setHeight(patternRect.height());
    337     }
    338     if (!repeatX || !repeatY) {
    339         cairo_rectangle(m_cr.get(), clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());
    340         cairo_clip(m_cr.get());
    341     }
    342 
    343     // Restoring cairo path.
    344     cairo_append_path(m_cr.get(), currentPath);
    345     cairo_path_destroy(currentPath);
    346 }
    347 
    348257} // namespace WebCore
    349258
  • trunk/Source/WebCore/platform/graphics/cairo/PlatformContextCairo.h

    r227051 r227055  
    7474    InterpolationQuality imageInterpolationQuality() const;
    7575
    76     enum PatternAdjustment { NoAdjustment, AdjustPatternForGlobalAlpha };
    77     void prepareForFilling(const Cairo::FillSource&, PatternAdjustment);
    78 
    79     enum AlphaPreservation { DoNotPreserveAlpha, PreserveAlpha };
    80     void prepareForStroking(const Cairo::StrokeSource&, AlphaPreservation);
    81 
    8276private:
    83     void clipForPatternFilling(const FloatSize&, const AffineTransform&, bool, bool);
    84 
    8577    RefPtr<cairo_t> m_cr;
    8678
Note: See TracChangeset for help on using the changeset viewer.