KHtml

helper.cpp
1 /*
2  * This file is part of the CSS implementation for KDE.
3  *
4  * Copyright (C) 1999-2003 Lars Knoll ([email protected])
5  * (C) David Carson <[email protected]>
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 License
18  * along with this library; see the file COPYING.LIB. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  *
22  */
23 #include "helper.h"
24 #include "khtmllayout.h"
25 #include <QMap>
26 #include <QPainter>
27 #include <dom/dom_string.h>
28 #include <xml/dom_stringimpl.h>
29 #include <rendering/render_object.h>
30 #include <kconfig.h>
31 #include <kcolorscheme.h>
32 #include <ksharedconfig.h>
33 #include <kconfiggroup.h>
34 #include <QToolTip>
35 #include "css/cssvalues.h"
36 
37 using namespace DOM;
38 using namespace khtml;
39 
40 namespace khtml
41 {
42 
43 QPainter *printpainter;
44 
45 void setPrintPainter(QPainter *printer)
46 {
47  printpainter = printer;
48 }
49 
50 void findWordBoundary(QChar *chars, int len, int position, int *start, int *end)
51 {
52  if (chars[position].isSpace()) {
53  int pos = position;
54  while (pos >= 0 && chars[pos].isSpace()) {
55  pos--;
56  }
57  *start = pos + 1;
58  pos = position;
59  while (pos < (int)len && chars[pos].isSpace()) {
60  pos++;
61  }
62  *end = pos;
63  } else if (chars[position].isPunct()) {
64  int pos = position;
65  while (pos >= 0 && chars[pos].isPunct()) {
66  pos--;
67  }
68  *start = pos + 1;
69  pos = position;
70  while (pos < (int)len && chars[pos].isPunct()) {
71  pos++;
72  }
73  *end = pos;
74  } else {
75  int pos = position;
76  while (pos >= 0 && !chars[pos].isSpace() && !chars[pos].isPunct()) {
77  pos--;
78  }
79  *start = pos + 1;
80  pos = position;
81  while (pos < (int)len && !chars[pos].isSpace() && !chars[pos].isPunct()) {
82  pos++;
83  }
84  *end = pos;
85  }
86 }
87 
88 }
89 
90 // color mapping code
91 struct colorMap {
92  int css_value;
93  QRgb color;
94 };
95 
96 static const colorMap cmap[] = {
97  { CSS_VAL_AQUA, 0xFF00FFFF },
98  { CSS_VAL_BLACK, 0xFF000000 },
99  { CSS_VAL_BLUE, 0xFF0000FF },
100  { CSS_VAL_CRIMSON, 0xFFDC143C },
101  { CSS_VAL_FUCHSIA, 0xFFFF00FF },
102  { CSS_VAL_GRAY, 0xFF808080 },
103  { CSS_VAL_GREEN, 0xFF008000 },
104  { CSS_VAL_INDIGO, 0xFF4B0082 },
105  { CSS_VAL_LIME, 0xFF00FF00 },
106  { CSS_VAL_MAROON, 0xFF800000 },
107  { CSS_VAL_NAVY, 0xFF000080 },
108  { CSS_VAL_OLIVE, 0xFF808000 },
109  { CSS_VAL_ORANGE, 0xFFFFA500 },
110  { CSS_VAL_PURPLE, 0xFF800080 },
111  { CSS_VAL_RED, 0xFFFF0000 },
112  { CSS_VAL_SILVER, 0xFFC0C0C0 },
113  { CSS_VAL_TEAL, 0xFF008080 },
114  { CSS_VAL_WHITE, 0xFFFFFFFF },
115  { CSS_VAL_YELLOW, 0xFFFFFF00 },
116  { CSS_VAL_TRANSPARENT, transparentColor },
117  { CSS_VAL_GREY, 0xff808080 },
118  { 0, 0 }
119 };
120 
121 struct uiColors {
122  int css_value;
123  QPalette::ColorGroup group;
124  QPalette::ColorRole role;
125 };
126 
127 // CSS 2.1 system color mapping
128 static const uiColors uimap[] = {
129  // MDI background color
130  { CSS_VAL_APPWORKSPACE, QPalette::Normal, QPalette::Mid },
131  // Button colors
132  { CSS_VAL_BUTTONFACE, QPalette::Normal, QPalette::Button },
133  { CSS_VAL_BUTTONHIGHLIGHT, QPalette::Normal, QPalette::Light },
134  { CSS_VAL_BUTTONSHADOW, QPalette::Normal, QPalette::Dark },
135  { CSS_VAL_BUTTONTEXT, QPalette::Normal, QPalette::ButtonText },
136  // Disabled text
137  { CSS_VAL_GRAYTEXT, QPalette::Disabled, QPalette::Text },
138  // Selected items
139  { CSS_VAL_HIGHLIGHTTEXT, QPalette::Normal, QPalette::HighlightedText },
140  { CSS_VAL_HIGHLIGHT, QPalette::Normal, QPalette::Highlight },
141  // Tooltips
142  { CSS_VAL_INFOBACKGROUND, QPalette::Normal, QPalette::ToolTipBase },
143  { CSS_VAL_INFOTEXT, QPalette::Normal, QPalette::ToolTipText },
144  // Menu colors
145  { CSS_VAL_MENU, QPalette::Normal, QPalette::Window },
146  { CSS_VAL_MENUTEXT, QPalette::Normal, QPalette::Text },
147  // Scroll bar color
148  { CSS_VAL_SCROLLBAR, QPalette::Normal, QPalette::Window },
149  // 3D elements
150  { CSS_VAL_THREEDDARKSHADOW, QPalette::Normal, QPalette::Dark },
151  { CSS_VAL_THREEDFACE, QPalette::Normal, QPalette::Button },
152  { CSS_VAL_THREEDHIGHLIGHT, QPalette::Normal, QPalette::Light },
153  { CSS_VAL_THREEDLIGHTSHADOW, QPalette::Normal, QPalette::Midlight },
154  { CSS_VAL_THREEDSHADOW, QPalette::Normal, QPalette::Mid },
155  // Window background
156  { CSS_VAL_WINDOW, QPalette::Normal, QPalette::Base },
157  // Window frame
158  { CSS_VAL_WINDOWFRAME, QPalette::Normal, QPalette::Window },
159  // WindowText
160  { CSS_VAL_WINDOWTEXT, QPalette::Normal, QPalette::Text },
161  { CSS_VAL_TEXT, QPalette::Normal, QPalette::Text },
163 };
164 
165 QColor khtml::colorForCSSValue(int css_value)
166 {
167  // try the regular ones first
168  const colorMap *col = cmap;
169  while (col->css_value && col->css_value != css_value) {
170  ++col;
171  }
172  if (col->css_value) {
173  return QColor::fromRgba(col->color);
174  } else if (css_value == CSS_VAL_INVERT) {
175  return QColor();
176  }
177 
178  const uiColors *uicol = uimap;
179  while (uicol->css_value && uicol->css_value != css_value) {
180  ++uicol;
181  }
182 #ifndef APPLE_CHANGES
183  if (!uicol->css_value) {
184  switch (css_value) {
185  case CSS_VAL_ACTIVEBORDER:
186  return qApp->palette().color(QPalette::Normal, QPalette::Window);
187  case CSS_VAL_ACTIVECAPTION:
189  case CSS_VAL_CAPTIONTEXT:
191  case CSS_VAL_INACTIVEBORDER:
192  return qApp->palette().color(QPalette::Inactive, QPalette::Window);
193  case CSS_VAL_INACTIVECAPTION:
195  case CSS_VAL_INACTIVECAPTIONTEXT:
197  case CSS_VAL_BACKGROUND: // Desktop background - no way to get this information from Plasma
198  return qApp->palette().color(QPalette::Normal, QPalette::Highlight);
199  default:
200  return QColor();
201  }
202  }
203 #endif
204 
205  const QPalette &pal = qApp->palette();
206  return pal.color(uicol->group, uicol->role);
207 }
208 
209 double calcHue(double temp1, double temp2, double hueVal)
210 {
211  if (hueVal < 0) {
212  hueVal++;
213  } else if (hueVal > 1) {
214  hueVal--;
215  }
216  if (hueVal * 6 < 1) {
217  return temp1 + (temp2 - temp1) * hueVal * 6;
218  }
219  if (hueVal * 2 < 1) {
220  return temp2;
221  }
222  if (hueVal * 3 < 2) {
223  return temp1 + (temp2 - temp1) * (2.0 / 3.0 - hueVal) * 6;
224  }
225  return temp1;
226 }
227 
228 // Explanation of this algorithm can be found in the CSS3 Color Module
229 // specification at https://www.w3.org/TR/css3-color/#hsl-color with further
230 // explanation available at https://en.wikipedia.org/wiki/HSL_and_HSV
231 
232 // all values are in the range of 0 to 1.0
233 QRgb khtml::qRgbaFromHsla(double h, double s, double l, double a)
234 {
235  double temp2 = l < 0.5 ? l * (1.0 + s) : l + s - l * s;
236  double temp1 = 2.0 * l - temp2;
237 
238  return qRgba(static_cast<int>(calcHue(temp1, temp2, h + 1.0 / 3.0) * 255),
239  static_cast<int>(calcHue(temp1, temp2, h) * 255),
240  static_cast<int>(calcHue(temp1, temp2, h - 1.0 / 3.0) * 255),
241  static_cast<int>(a * 255));
242 }
243 
244 /** finds out the background color of an element
245  * @param obj render object
246  * @return the background color. It is guaranteed that a valid color is returned.
247  */
249 {
250  QColor result;
251  while (!obj->isCanvas()) {
252  result = obj->style()->backgroundColor();
253  if (result.isValid()) {
254  return result;
255  }
256 
257  obj = obj->container();
258  }/*wend*/
259 
260  // everything transparent? Use base then.
261  return obj->style()->palette().color(QPalette::Active, QPalette::Base);
262 }
263 
264 /** checks whether the given colors have enough contrast
265  * @returns @p true if contrast is ok.
266  */
267 bool khtml::hasSufficientContrast(const QColor &c1, const QColor &c2)
268 {
269 // New version from Germain Garand, better suited for contrast measurement
270 #if 1
271 
272 #define HUE_DISTANCE 40
273 #define CONTRAST_DISTANCE 10
274 
275  int h1, s1, v1, h2, s2, v2;
276  int hdist = -CONTRAST_DISTANCE;
277  c1.getHsv(&h1, &s1, &v1);
278  c2.getHsv(&h2, &s2, &v2);
279  if (h1 != -1 && h2 != -1) { // grey values have no hue
280  hdist = qAbs(h1 - h2);
281  if (hdist > 180) {
282  hdist = 360 - hdist;
283  }
284  if (hdist < HUE_DISTANCE) {
285  hdist -= HUE_DISTANCE;
286  // see if they are high key or low key colours
287  bool hk1 = h1 >= 45 && h1 <= 225;
288  bool hk2 = h2 >= 45 && h2 <= 225;
289  if (hk1 && hk2) {
290  hdist = (5 * hdist) / 3;
291  } else if (!hk1 && !hk2) {
292  hdist = (7 * hdist) / 4;
293  }
294  }
295  hdist = qMin(hdist, HUE_DISTANCE * 2);
296  }
297  return hdist + (qAbs(s1 - s2) * 128) / (160 + qMin(s1, s2)) + qAbs(v1 - v2) > CONTRAST_DISTANCE;
298 
299 #undef CONTRAST_DISTANCE
300 #undef HUE_DISTANCE
301 
302 #else // orginal fast but primitive version by me (LS)
303 
304 // ### arbitrary value, to be adapted if necessary (LS)
305 #define CONTRAST_DISTANCE 32
306 
307  if (qAbs(c1.Qt::red() - c2.Qt::red()) > CONTRAST_DISTANCE) {
308  return true;
309  }
310  if (qAbs(c1.Qt::green() - c2.Qt::green()) > CONTRAST_DISTANCE) {
311  return true;
312  }
313  if (qAbs(c1.Qt::blue() - c2.Qt::blue()) > CONTRAST_DISTANCE) {
314  return true;
315  }
316 
317  return false;
318 
319 #undef CONTRAST_DISTANCE
320 
321 #endif
322 }
QBrush background(BackgroundRole=NormalBackground) const
This file is part of the HTML rendering engine for KDE.
bool hasSufficientContrast(const QColor &c1, const QColor &c2)
checks whether the given colors have enough contrast
Definition: helper.cpp:267
QColor retrieveBackgroundColor(const RenderObject *obj)
finds out the background color of an element
Definition: helper.cpp:248
const QColor & color(QPalette::ColorGroup group, QPalette::ColorRole role) const const
void getHsv(int *h, int *s, int *v, int *a) const const
const QColor & color() const const
QBrush foreground(ForegroundRole=NormalText) const
RenderObject * container() const
returns the object containing this one.
QColor fromRgba(QRgb rgba)
This library provides a full-featured HTML parser and widget.
Base Class for all rendering tree objects.
bool isValid() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Oct 26 2021 22:48:01 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.