Home | History | Annotate | Download | only in cairo
      1 /*
      2  * Copyright (C) 2004 Red Hat, Inc.
      3  * Copyright (C) 2010 Brent Fulgham <bfulgham (at) webkit.org>
      4  *
      5  * Based on Pango sources (see pangocairo-render.c)
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Library General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Library General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Library General Public
     18  * License along with this library; if not, write to the
     19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     20  * Boston, MA 02111-1307, USA.
     21  *
     22  */
     23 
     24 #if USE(CAIRO)
     25 
     26 #ifndef DrawErrorUnderline_h
     27 #define DrawErrorUnderline_h
     28 
     29 #include <cairo.h>
     30 
     31 //
     32 // Draws an error underline that looks like one of:
     33 //
     34 //              H       E                H
     35 //     /\      /\      /\        /\      /\               -
     36 //   A/  \    /  \    /  \     A/  \    /  \              |
     37 //    \   \  /    \  /   /D     \   \  /    \             |
     38 //     \   \/  C   \/   /        \   \/   C  \            | height = heightSquares * square
     39 //      \      /\  F   /          \  F   /\   \           |
     40 //       \    /  \    /            \    /  \   \G         |
     41 //        \  /    \  /              \  /    \  /          |
     42 //         \/      \/                \/      \/           -
     43 //         B                         B
     44 //         |---|
     45 //       unitWidth = (heightSquares - 1) * square
     46 //
     47 // The x, y, width, height passed in give the desired bounding box;
     48 // x/width are adjusted to make the underline a integer number of units
     49 // wide.
     50 //
     51 static inline void drawErrorUnderline(cairo_t* cr, double x, double y, double width, double height)
     52 {
     53     static const double heightSquares = 2.5;
     54 
     55     double square = height / heightSquares;
     56     double halfSquare = 0.5 * square;
     57 
     58     double unitWidth = (heightSquares - 1.0) * square;
     59     int widthUnits = static_cast<int>((width + 0.5 * unitWidth) / unitWidth);
     60 
     61     x += 0.5 * (width - widthUnits * unitWidth);
     62     width = widthUnits * unitWidth;
     63 
     64     double bottom = y + height;
     65     double top = y;
     66 
     67     // Bottom of squiggle
     68     cairo_move_to(cr, x - halfSquare, top + halfSquare); // A
     69 
     70     int i = 0;
     71     for (i = 0; i < widthUnits; i += 2) {
     72         double middle = x + (i + 1) * unitWidth;
     73         double right = x + (i + 2) * unitWidth;
     74 
     75         cairo_line_to(cr, middle, bottom); // B
     76 
     77         if (i + 2 == widthUnits)
     78             cairo_line_to(cr, right + halfSquare, top + halfSquare); // D
     79         else if (i + 1 != widthUnits)
     80             cairo_line_to(cr, right, top + square); // C
     81     }
     82 
     83     // Top of squiggle
     84     for (i -= 2; i >= 0; i -= 2) {
     85         double left = x + i * unitWidth;
     86         double middle = x + (i + 1) * unitWidth;
     87         double right = x + (i + 2) * unitWidth;
     88 
     89         if (i + 1 == widthUnits)
     90             cairo_line_to(cr, middle + halfSquare, bottom - halfSquare); // G
     91         else {
     92             if (i + 2 == widthUnits)
     93                 cairo_line_to(cr, right, top); // E
     94 
     95             cairo_line_to(cr, middle, bottom - halfSquare); // F
     96         }
     97 
     98         cairo_line_to(cr, left, top); // H
     99     }
    100 }
    101 
    102 #endif // DrawErrorUnderline_h
    103 
    104 #endif
    105