A never ending story.

Michael Reiher michael.reiher at gmx.de
Tue Oct 29 00:29:40 GMT 2002


Michael Reiher wrote:
> 
> I attached a revised patch. I changed helper.cpp to read the decoration colors
> from config file again.
> 
Ouch! I should at least try to compile it before. Fixed version of helper.cpp
attached

Greets

Michael
-------------- next part --------------
/*
 * This file is part of the CSS implementation for KDE.
 *
 * Copyright (C) 1999 Lars Knoll (knoll at kde.org)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * $Id: helper.cpp,v 1.51 2002/10/27 17:13:23 mueller Exp $
 */
#include "helper.h"
#include <khtmllayout.h>
#include <qmap.h>
#include <qpainter.h>
#include <dom/dom_string.h>
#include <xml/dom_stringimpl.h>
#include <qptrlist.h>
#include <kstaticdeleter.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kglobalsettings.h>
#include <kdebug.h>
#include <qtooltip.h>

using namespace DOM;
using namespace khtml;

struct HTMLColors {
    QMap<QString,QColor> map;
    HTMLColors();
};

struct colorMap {
    const char * name;
    const char * value;
};

static const colorMap cmap[] = {
   { "green", "#008000" },
   { "gray", "#808080" },
   { "grey", "#808080" },
   { "silver", "#c0c0c0" },
   { "lime", "#00ff00" },
   { "olive", "#808000" },
   { "maroon", "#800000" },
   { "purple", "#800080" },
   { "teal", "#008080" },
   { "fuchsia", "#ff00ff" },
   { "aqua", "#00ffff" },
   { "crimson", "#dc143c" },
   { "indigo", "#4b0082" },
   { 0, 0 }
};

struct decoColors {
    const char * name;
    const char * configGroup;
    const char * configEntry;
    QPalette::ColorGroup group;
    QColorGroup::ColorRole role;
};

const char * const wmgroup = "WM";

static const decoColors decomap[] = {
	// Active window border.
  { "activeborder", wmgroup, "background", QPalette::Active, QColorGroup::Light },
	// Active window caption.
  { "activecaption", wmgroup, "background", QPalette::Active, QColorGroup::Text },
  // Text in caption, size box, and scrollbar arrow box.
  { "captiontext", wmgroup, "activeForeground", QPalette::Active, QColorGroup::Text },
  // Inactive window border.
  { "inactiveborder", wmgroup, "background", QPalette::Disabled, QColorGroup::Background },
  // Inactive window caption.
  { "inactivecaption", wmgroup, "inactiveBackground", QPalette::Disabled, QColorGroup::Background },
  // Color of text in an inactive caption.
  { "inactivecaptiontext", wmgroup, "inactiveForeground", QPalette::Disabled, QColorGroup::Text },
  { 0, 0, 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
};

struct widgetColors {
    const char * name;
    QPalette::ColorGroup group;
    QColorGroup::ColorRole role;
};

static const widgetColors widgetmap[] = {
	// Face color for three-dimensional display elements.
    { "buttonface", QPalette::Inactive, QColorGroup::Button }, // MR: shouldn't this be QColorGroup::ButtonText
	// Dark shadow for three-dimensional display elements (for edges facing away from the light source).
    { "buttonhighlight", QPalette::Inactive, QColorGroup::Light },
	// Shadow color for three-dimensional display elements.
    { "buttonshadow", QPalette::Inactive, QColorGroup::Shadow },
	// Text on push buttons.
    { "buttontext", QPalette::Inactive, QColorGroup::ButtonText },
	// Dark shadow for three-dimensional display elements.
    { "threeddarkshadow", QPalette::Inactive, QColorGroup::Dark },
	// Face color for three-dimensional display elements.
    { "threedface", QPalette::Inactive, QColorGroup::Button }, // MR: shouldn't this be QColorGroup::ButtonText
	// Highlight color for three-dimensional display elements.
    { "threedhighlight", QPalette::Inactive, QColorGroup::Light },
	// Light color for three-dimensional display elements (for edges facing the light source).
    { "threedlightshadow", QPalette::Inactive, QColorGroup::Midlight },
	// Dark shadow for three-dimensional display elements.
    { "threedshadow", QPalette::Inactive, QColorGroup::Shadow },

    { "graytext", QPalette::Disabled, QColorGroup::Text },

	// Menu background
    { "menu", QPalette::Inactive, QColorGroup::Background },
	// Text in menus
    { "menutext", QPalette::Inactive, QColorGroup::Background }, // MR: shouldn't this be QColorGroup::Foreground

        // Text of item(s) selected in a control.
    { "highlight", QPalette::Inactive, QColorGroup::Background }, // MR: shouldn't this be QColorGroup::Highlight

    // Text of item(s) selected in a control.
    { "highlighttext", QPalette::Inactive, QColorGroup::Background }, // MR: shouldn't this be QColorGroup::HighlightedText

	// Background color of multiple document interface.
    { "appworkspace", QPalette::Inactive, QColorGroup::Text }, // MR: shouldn't this be QColorGroup::Base

	// Scroll bar gray area.
    { "scrollbar", QPalette::Inactive, QColorGroup::Background },

	// Window background.
    { "window", QPalette::Inactive, QColorGroup::Background },
	// Window frame.
    { "windowframe", QPalette::Inactive, QColorGroup::Background },
        // WindowText
    { "windowtext", QPalette::Inactive, QColorGroup::Text }, // MR: shouldn't this be QColorGroup::Foreground
    { "text", QPalette::Inactive, QColorGroup::Text },
    { 0, QPalette::NColorGroups, QColorGroup::NColorRoles }
};

HTMLColors::HTMLColors()
{
  // Local HTML palette for widget colors ( code taken from KApplication )
  KConfig *config = KGlobal::config();
  QString lastConfigGroup1 = config->group();
  config->setGroup( "HTML Colors" );

  int contrast_ = KGlobalSettings::contrast();
  const QPalette &defaultPal = kapp->palette();

  QColor background = config->readColorEntry( "background", &defaultPal.active().background() );
  QColor foreground = config->readColorEntry( "foreground", &defaultPal.active().foreground() );
  QColor button = config->readColorEntry( "buttonBackground", &background );
  QColor buttonText = config->readColorEntry( "buttonForeground", &foreground );
  QColor highlight = config->readColorEntry( "selectBackground", &defaultPal.active().highlight() );
  QColor highlightedText = config->readColorEntry( "selectForeground", &defaultPal.active().highlightedText() );
  QColor base = config->readColorEntry( "windowBackground", &defaultPal.active().base() );
  QColor baseText = config->readColorEntry( "windowForeground", &defaultPal.active().text() );
  QColor link = config->readColorEntry( "linkColor", &defaultPal.active().link() );
  QColor visitedLink = config->readColorEntry( "visitedLinkColor", &defaultPal.active().linkVisited() );

  int highlightVal = 100 + (2*contrast_+4)*16/10;
  int lowlightVal = 100 + (2*contrast_+4)*10;

  QColor disfg = foreground;

  int h, s, v;
  disfg.hsv( &h, &s, &v );
  if (v > 128)
    // dark bg, light fg - need a darker disabled fg
    disfg = disfg.dark(lowlightVal);
  else if (disfg != Qt::black)
    // light bg, dark fg - need a lighter disabled fg - but only if !black
    disfg = disfg.light(highlightVal);
  else
    // black fg - use darkgrey disabled fg
    disfg = Qt::darkGray;


  QColorGroup disabledgrp(disfg, background,
                          background.light(highlightVal),
                          background.dark(lowlightVal),
                          background.dark(120),
                          background.dark(120), base);

  QColorGroup colgrp(foreground, background, background.light(highlightVal),
                     background.dark(lowlightVal),
                     background.dark(120),
                     baseText, base);

  int inlowlightVal = lowlightVal-25;
  if(inlowlightVal < 120)
    inlowlightVal = 120;

  colgrp.setColor(QColorGroup::Highlight, highlight);
  colgrp.setColor(QColorGroup::HighlightedText, highlightedText);
  colgrp.setColor(QColorGroup::Button, button);
  colgrp.setColor(QColorGroup::ButtonText, buttonText);
  colgrp.setColor(QColorGroup::Midlight, background.light(110));
  colgrp.setColor(QColorGroup::Link, link);
  colgrp.setColor(QColorGroup::LinkVisited, visitedLink);

  disabledgrp.setColor(QColorGroup::Button, button);

  QColor disbtntext = buttonText;
  disbtntext.hsv( &h, &s, &v );
  if (v > 128)
    // dark button, light buttonText - need a darker disabled buttonText
    disbtntext = disbtntext.dark(lowlightVal);
  else if (disbtntext != Qt::black)
    // light buttonText, dark button - need a lighter disabled buttonText - but only if !black
    disbtntext = disbtntext.light(highlightVal);
  else
    // black button - use darkgrey disabled buttonText
    disbtntext = Qt::darkGray;

  disabledgrp.setColor(QColorGroup::ButtonText, disbtntext);
  disabledgrp.setColor(QColorGroup::Midlight, background.light(110));
  disabledgrp.setColor(QColorGroup::Link, link);
  disabledgrp.setColor(QColorGroup::LinkVisited, visitedLink);

  QPalette htmlPal(colgrp, disabledgrp, colgrp);

  config->setGroup( lastConfigGroup1 );


  const colorMap *color = cmap;
  while ( color->name ) {
    map[color->name] = color->value;
    ++color;
  }

  // ### react to style changes
  // see http://www.richinstyle.com for details

  /* Mapping system settings to CSS 2
   * Tried hard to get an appropriate mapping - schlpbch
   */

  // set widget colors
  const widgetColors *widgetcol = widgetmap;
  while( widgetcol->name ) {
    QColor c = htmlPal.color( widgetcol->group, widgetcol->role );
    map[widgetcol->name] = c;
    ++widgetcol;
  }

  // set decoration colors
  const decoColors *decocol = decomap;
  const char *lastConfigGroup = 0;
  while( decocol->name ) {
    if ( lastConfigGroup != decocol->configGroup ) {
      lastConfigGroup = decocol->configGroup;
	    config->setGroup( lastConfigGroup );
    }
    QColor c = htmlPal.color( decocol->group, decocol->role );
    if ( decocol->configEntry )
	    c = config->readColorEntry( decocol->configEntry, &c );
    map[decocol->name] = c;
    ++decocol;
  }

#ifndef QT_NO_TOOLTIP
  // InfoBackground
  map["infobackground"] = QToolTip::palette().inactive().background();
  // InfoText
  map["infotext"] = QToolTip::palette().inactive().foreground();
#endif

  KConfig bckgrConfig("kdesktoprc", true, false); // No multi-screen support
  bckgrConfig.setGroup("Desktop0");
  // Desktop background.
  map["background"] = bckgrConfig.readColorEntry("Color1", &htmlPal.disabled().background());
};



static HTMLColors *htmlColors = 0L;

static KStaticDeleter<HTMLColors> hcsd;

QRgb khtml::parseColor(QString name, bool strictParsing)
{
    if( !htmlColors )
        htmlColors = hcsd.setObject( new HTMLColors );

    int pos;
    // remove white spaces for those broken websites out there :-(
    while ( ( pos = name.find( ' ' ) ) != -1 )  name.remove( pos, 1 );

    int len = name.length();

    if (!len || (strictParsing && len < 3))
        return invalidColor;

    if(len == 11 && name.find("transparent", 0, false) == 0)
        return transparentColor;

    if(len == 10 && name == "-konq-text")
        return defaultTextColor;

    // also recognize "color=ffffff"
    if (len == 6)
    {
        bool ok;
        int val = name.toInt(&ok, 16);
        if(ok)
            return (0xff << 24) | val;

        // recognize #12345 (duplicate the last character)
        if(!strictParsing && name[0] == '#') {
            bool ok;
            int val = name.right(5).toInt(&ok, 16);
            if(ok)
                return (0xff << 24) | (val * 16 + ( val&0xf ));
        }
        if ( !name[0].isLetter() )
            return invalidColor;
    }

    // #fffffff as found on msdn.microsoft.com
    if ( name[0] == '#' && len > 7)
        name = name.left(7);

    if ( len > 4 && name[0].lower() == 'r' && name[1].lower() == 'g' &&
         name[2].lower() == 'b' && name[3] == '(' &&
         name[len-1] == ')')
    {
        // CSS like rgb(r, g, b) style
        DOMString rgb = name.mid(4, name.length()-5);
        int count;
        khtml::Length* l = rgb.implementation()->toLengthArray(count);
        if (count != 3)
            return transparentColor;

        int c[3];
        for (int i = 0; i < 3; ++i) {
            c[i] = l[i].width(255);
            if (c[i] < 0) c[i] = 0;
            if (c[i] > 255) c[i] = 255;
        }

        QRgb col = qRgb(c[0], c[1], c[2]);
        delete [] l;
        return col;
    }

    QColor tc = htmlColors->map[name];
    if ( !tc.isValid() )
        tc = htmlColors->map[name.lower()];

    if (tc.isValid())
        return tc.rgb();

    tc.setNamedColor(name);
    if (tc.isValid()) return tc.rgb();

    tc.setNamedColor(name.lower());
    if (tc.isValid()) return tc.rgb();

    if(!strictParsing) {
        bool hasalpha = false;
        for(unsigned int i = 0; i < name.length(); i++)
            if(name[i].isLetterOrNumber()) {
                hasalpha = true;
                break;
            }

        if(!hasalpha)
            return qRgb(0, 0, 0);
    }

    return invalidColor;
}

QPainter *khtml::printpainter = 0;

void khtml::setPrintPainter( QPainter *printer )
{
    printpainter = printer;
}


More information about the kfm-devel mailing list