1 /*
2 * Copyright (C) 2004 Red Hat, Inc.
3 * Copyright (C) 2010 Brent Fulgham <bfulgham@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 //
drawErrorUnderline(cairo_t * cr,double x,double y,double width,double height)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