diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2011-11-06 15:56:40 -0600 |
commit | e16866e072f94410321d70daedbcb855ea878cac (patch) | |
tree | ee3f52eabde7da1a0e6ca845fb9c2813cf1558cf /kdefx | |
parent | a58c20c1a7593631a1b50213c805507ebc16adaf (diff) | |
download | tdelibs-e16866e072f94410321d70daedbcb855ea878cac.tar.gz tdelibs-e16866e072f94410321d70daedbcb855ea878cac.zip |
Actually move the kde files that were renamed in the last commit
Diffstat (limited to 'kdefx')
-rw-r--r-- | kdefx/CMakeLists.txt | 48 | ||||
-rw-r--r-- | kdefx/Mainpage.dox | 32 | ||||
-rw-r--r-- | kdefx/Makefile.am | 45 | ||||
-rw-r--r-- | kdefx/configure.in.in | 63 | ||||
-rw-r--r-- | kdefx/kcpuinfo.cpp | 176 | ||||
-rw-r--r-- | kdefx/kcpuinfo.h | 70 | ||||
-rw-r--r-- | kdefx/kdrawutil.cpp | 264 | ||||
-rw-r--r-- | kdefx/kdrawutil.h | 180 | ||||
-rw-r--r-- | kdefx/kimageeffect.cpp | 4980 | ||||
-rw-r--r-- | kdefx/kimageeffect.h | 817 | ||||
-rw-r--r-- | kdefx/kpixmap.cpp | 389 | ||||
-rw-r--r-- | kdefx/kpixmap.h | 213 | ||||
-rw-r--r-- | kdefx/kpixmapeffect.cpp | 325 | ||||
-rw-r--r-- | kdefx/kpixmapeffect.h | 218 | ||||
-rw-r--r-- | kdefx/kpixmapsplitter.cpp | 95 | ||||
-rw-r--r-- | kdefx/kpixmapsplitter.h | 123 | ||||
-rw-r--r-- | kdefx/kstyle.cpp | 2370 | ||||
-rw-r--r-- | kdefx/kstyle.h | 356 | ||||
-rw-r--r-- | kdefx/libkdefx.nmcheck | 12 | ||||
-rw-r--r-- | kdefx/libkdefx_weak.nmcheck | 3 |
20 files changed, 0 insertions, 10779 deletions
diff --git a/kdefx/CMakeLists.txt b/kdefx/CMakeLists.txt deleted file mode 100644 index 1aa52627f..000000000 --- a/kdefx/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -################################################# -# -# (C) 2010 Serghei Amelian -# serghei (DOT) amelian (AT) gmail.com -# -# Improvements and feedback are welcome -# -# This file is released under GPL >= 2 -# -################################################# - -include_directories( - ${TQT_INCLUDE_DIRS} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_BINARY_DIR}/tdecore - ${CMAKE_SOURCE_DIR}/tdecore -) - -link_directories( - ${TQT_LIBRARY_DIRS} -) - - -##### headers ################################### - -install( FILES - kpixmap.h kpixmapsplitter.h kpixmapeffect.h - kimageeffect.h kdrawutil.h kstyle.h kcpuinfo.h - DESTINATION ${INCLUDE_INSTALL_DIR} ) - - -##### libtdefx ################################## - -set( target tdefx ) - -set( ${target}_SRCS - kpixmap.cpp kpixmapsplitter.cpp kpixmapeffect.cpp - kimageeffect.cpp kdrawutil.cpp kstyle.cpp kcpuinfo.cpp -) - -tde_add_library( ${target} SHARED AUTOMOC - SOURCES ${${target}_SRCS} - VERSION 4.2.0 - LINK ${TQT_LIBRARIES} ${XRENDER_LIBRARIES} - DESTINATION ${LIB_INSTALL_DIR} -) diff --git a/kdefx/Mainpage.dox b/kdefx/Mainpage.dox deleted file mode 100644 index 65fcadfc8..000000000 --- a/kdefx/Mainpage.dox +++ /dev/null @@ -1,32 +0,0 @@ -/** - * \mainpage The Trinity special effects [fx] Library - * - * This library provides various classes related to image and pixmap - * manipulation, a class that provides information about CPU support - * for architecture specific features, as well as the base class for - * the %Trinity widget styles. - * - * The two graphical effects classes, KImageEffect and KPixmapEffect, - * provide static methods for applying graphical effects to images and - * pixmaps respectively. KImageEffect also provides highly optimized - * methods for compositing images. - * - * A class that's related to those two is KPixmapSplitter, which is - * used for calculating the positions of items in pixmaps with - * multiple items arranged in rows and columns. - * Another is KPixmap, which extends QPixmap with the capability to - * ensure that a 256 color pixmap uses a specific system wide - * palette. - * - * The KCPUInfo class provides a means for applications to obtain - * information at runtime about processor support for certain - * architecture extensions that are useful when processing images, - * such as MMX, SSE, 3DNow! and AltiVec. - * - * KStyle is the base class for the %Trinity widget styles. It simplifies - * and extends the QStyle API in order to make style coding easier. - * It also provides an internal menu transparency and drop shadow - * engine, which means that all styles inheriting this class will - * automatically support those features. - */ - diff --git a/kdefx/Makefile.am b/kdefx/Makefile.am deleted file mode 100644 index 2b588ba54..000000000 --- a/kdefx/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ - -# This file is part of the KDE libraries -# Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) -# (C) 1997 Stephan Kulow (coolo@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 General Public License -# along with this library; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -# Boston, MA 02110-1301, USA. - -#SUBDIRS = . tests - -INCLUDES= $(all_includes) - -lib_LTLIBRARIES = libtdefx.la -libtdefx_la_LDFLAGS = $(KDE_RPATH) $(KDE_MT_LDFLAGS) $(all_libraries) -no-undefined -version-info 6:0:2 -libtdefx_la_LIBADD = $(LIB_QT) $(LIB_XRENDER) $(LIB_X11) -libtdefx_la_NMCHECK = $(srcdir)/libtdefx.nmcheck -libtdefx_la_NMCHECKWEAK = $(srcdir)/libtdefx_weak.nmcheck $(top_srcdir)/tdecore/libqt-mt_weak.nmcheck \ - $(top_srcdir)/tdecore/standard_weak.nmcheck - -include_HEADERS = kpixmap.h kpixmapsplitter.h \ - kpixmapeffect.h kimageeffect.h kdrawutil.h kstyle.h kcpuinfo.h - -libtdefx_la_SOURCES = kpixmap.cpp kpixmapsplitter.cpp \ - kpixmapeffect.cpp kimageeffect.cpp kdrawutil.cpp kstyle.cpp \ - kcpuinfo.cpp - -METASOURCES = AUTO - -EXTRA_DIST = Mainpage.dox - -DOXYGEN_REFERENCES = tdecore -include ../admin/Doxyfile.am - diff --git a/kdefx/configure.in.in b/kdefx/configure.in.in deleted file mode 100644 index 9afed6f96..000000000 --- a/kdefx/configure.in.in +++ /dev/null @@ -1,63 +0,0 @@ - -dnl ----------------------------------------------------- -dnl XRender check -dnl ----------------------------------------------------- -LIB_XRENDER= -if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then - KDE_CHECK_HEADER(X11/extensions/Xrender.h, [xrender_h=yes], [xrender_h=no]) - if test "$xrender_h" = yes; then - KDE_CHECK_LIB(Xrender, XRenderComposite, [ - LIB_XRENDER=-lXrender - AC_DEFINE_UNQUOTED(HAVE_XRENDER, 1, [Defined if your system has XRender support]) - ], [], -lXext -lX11 $X_EXTRA_LIBS) - fi -fi -AC_SUBST(LIB_XRENDER) - -dnl ----------------------------------------------------- -dnl IA32 checks -dnl ----------------------------------------------------- -case $host_cpu in - i*86 ) - AC_MSG_CHECKING(for assembler support for IA32 extensions) - - dnl MMX check - AC_TRY_COMPILE(, [ __asm__("pxor %mm0, %mm0") ], - [ - echo $ECHO_N "MMX yes$ECHO_C" - AC_DEFINE_UNQUOTED(HAVE_X86_MMX, 1, [Define to 1 if the assembler supports MMX instructions.]) - ], [ echo $ECHO_N "MMX no$ECHO_C" ]) - - dnl SSE check - AC_TRY_COMPILE(,[ __asm__("xorps %xmm0, %xmm0") ], - [ - echo $ECHO_N ", SSE yes$ECHO_C" - AC_DEFINE_UNQUOTED(HAVE_X86_SSE, 1, [Define to 1 if the assembler supports SSE instructions.]) - ], [ echo $ECHO_N ", SSE no$ECHO_C" ]) - - dnl SSE2 check - AC_TRY_COMPILE(, [ __asm__("xorpd %xmm0, %xmm0") ], - [ - echo $ECHO_N ", SSE2 yes$ECHO_C" - AC_DEFINE_UNQUOTED(HAVE_X86_SSE2, 1, [Define to 1 if the assembler supports SSE2 instructions.]) - ], [ echo $ECHO_N ", SSE2 no$ECHO_C" ]) - - dnl 3DNOW check - AC_TRY_COMPILE(, [ __asm__("femms") ], - [ - echo $ECHO_N ", 3DNOW yes$ECHO_C" - AC_DEFINE_UNQUOTED(HAVE_X86_3DNOW, 1, [Define to 1 if the assembler supports 3DNOW instructions.]) - ], [ echo $ECHO_N ", 3DNOW no$ECHO_C" ]) - echo - ;; - powerpc ) - AC_MSG_CHECKING(for assembler support for AltiVec instructions) - dnl AltiVec check - AC_TRY_COMPILE(, [ __asm__("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0" : : "r"(-1) ) ], - [ - echo $ECHO_N " yes$ECHO_C" - AC_DEFINE_UNQUOTED(HAVE_PPC_ALTIVEC, 1, [Define to 1 if the assembler supports AltiVec instructions.]) - ], [ echo $ECHO_N ", AltiVec no$ECHO_C" ]) - echo - ;; -esac diff --git a/kdefx/kcpuinfo.cpp b/kdefx/kcpuinfo.cpp deleted file mode 100644 index 97c99f8d9..000000000 --- a/kdefx/kcpuinfo.cpp +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Fredrik Höglund <fredrik@kde.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <csignal> -#include <csetjmp> - -#include <config.h> -#include "kcpuinfo.h" - - -#if defined(__GNUC__) || defined(__INTEL_COMPILER) -# define HAVE_GNU_INLINE_ASM -#endif - -typedef void (*kde_sighandler_t) (int); - -#ifdef __i386__ -static jmp_buf env; - -// Sighandler for the SSE OS support check -static void sighandler( int ) -{ - std::longjmp( env, 1 ); -} -#endif - -#ifdef __PPC__ -static sigjmp_buf KDE_NO_EXPORT jmpbuf; -static sig_atomic_t KDE_NO_EXPORT canjump = 0; - -static void KDE_NO_EXPORT sigill_handler( int sig ) -{ - if ( !canjump ) { - signal( sig, SIG_DFL ); - raise( sig ); - } - canjump = 0; - siglongjmp( jmpbuf, 1 ); -} -#endif - -static int getCpuFeatures() -{ - volatile int features = 0; - -#if defined( HAVE_GNU_INLINE_ASM ) -#if defined( __i386__ ) - bool haveCPUID = false; - bool have3DNOW = false; - int result = 0; - - // First check if the CPU supports the CPUID instruction - __asm__ __volatile__( - // Try to toggle the CPUID bit in the EFLAGS register - "pushf \n\t" // Push the EFLAGS register onto the stack - "popl %%ecx \n\t" // Pop the value into ECX - "movl %%ecx, %%edx \n\t" // Copy ECX to EDX - "xorl $0x00200000, %%ecx \n\t" // Toggle bit 21 (CPUID) in ECX - "pushl %%ecx \n\t" // Push the modified value onto the stack - "popf \n\t" // Pop it back into EFLAGS - - // Check if the CPUID bit was successfully toggled - "pushf \n\t" // Push EFLAGS back onto the stack - "popl %%ecx \n\t" // Pop the value into ECX - "xorl %%eax, %%eax \n\t" // Zero out the EAX register - "cmpl %%ecx, %%edx \n\t" // Compare ECX with EDX - "je .Lno_cpuid_support%= \n\t" // Jump if they're identical - "movl $1, %%eax \n\t" // Set EAX to true - ".Lno_cpuid_support%=: \n\t" - : "=a"(haveCPUID) : : "%ecx", "%edx" ); - - // If we don't have CPUID we won't have the other extensions either - if ( ! haveCPUID ) - return 0L; - - // Execute CPUID with the feature request bit set - __asm__ __volatile__( - "pushl %%ebx \n\t" // Save EBX - "movl $1, %%eax \n\t" // Set EAX to 1 (features request) - "cpuid \n\t" // Call CPUID - "popl %%ebx \n\t" // Restore EBX - : "=d"(result) : : "%eax", "%ecx" ); - - // Test bit 23 (MMX support) - if ( result & 0x00800000 ) - features |= KCPUInfo::IntelMMX; - - __asm__ __volatile__( - "pushl %%ebx \n\t" - "movl $0x80000000, %%eax \n\t" - "cpuid \n\t" - "cmpl $0x80000000, %%eax \n\t" - "jbe .Lno_extended%= \n\t" - "movl $0x80000001, %%eax \n\t" - "cpuid \n\t" - "test $0x80000000, %%edx \n\t" - "jz .Lno_extended%= \n\t" - "movl $1, %%eax \n\t" // // Set EAX to true - ".Lno_extended%=: \n\t" - "popl %%ebx \n\t" // Restore EBX - : "=a"(have3DNOW) : ); - - if ( have3DNOW ) - features |= KCPUInfo::AMD3DNOW; - -#ifdef HAVE_X86_SSE - // Test bit 25 (SSE support) - if ( result & 0x00200000 ) { - features |= KCPUInfo::IntelSSE; - - // OS support test for SSE. - // Install our own sighandler for SIGILL. - kde_sighandler_t oldhandler = std::signal( SIGILL, sighandler ); - - // Try executing an SSE insn to see if we get a SIGILL - if ( setjmp( env ) ) - features ^= KCPUInfo::IntelSSE; // The OS support test failed - else - __asm__ __volatile__("xorps %xmm0, %xmm0"); - - // Restore the default sighandler - std::signal( SIGILL, oldhandler ); - - // Test bit 26 (SSE2 support) - if ( (result & 0x00400000) && (features & KCPUInfo::IntelSSE) ) - features |= KCPUInfo::IntelSSE2; - - // Note: The OS requirements for SSE2 are the same as for SSE - // so we don't have to do any additional tests for that. - } -#endif // HAVE_X86_SSE -#elif defined __PPC__ && defined HAVE_PPC_ALTIVEC - signal( SIGILL, sigill_handler ); - if ( sigsetjmp( jmpbuf, 1 ) ) { - signal( SIGILL, SIG_DFL ); - } else { - canjump = 1; - __asm__ __volatile__( "mtspr 256, %0\n\t" - "vand %%v0, %%v0, %%v0" - : /* none */ - : "r" (-1) ); - signal( SIGILL, SIG_DFL ); - features |= KCPUInfo::AltiVec; - } -#endif // __i386__ -#endif //HAVE_GNU_INLINE_ASM - - return features; -} - -unsigned int KCPUInfo::s_features = getCpuFeatures(); - - diff --git a/kdefx/kcpuinfo.h b/kdefx/kcpuinfo.h deleted file mode 100644 index ce39ded82..000000000 --- a/kdefx/kcpuinfo.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 2003 Fredrik Höglund <fredrik@kde.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __KCPUINFO_H -#define __KCPUINFO_H - -#include <kdelibs_export.h> - -/** - * This class provides a means for applications to obtain information at - * runtime about processor support for certain architecture extensions, - * such as MMX, SSE, 3DNow and AltiVec. - * - * @since 3.2 - */ -class KDEFX_EXPORT KCPUInfo -{ - public: - /** - * This enum contains the list of architecture extensions you - * can query. - */ - enum Extensions { - IntelMMX = 1 << 0, //!< Intel's MMX instructions. - IntelSSE = 1 << 1, //!< Intel's SSE instructions. - IntelSSE2 = 1 << 2, //!< Intel's SSE2 instructions. - AMD3DNOW = 1 << 3, //!< AMD 3DNOW instructions - AltiVec = 1 << 4 //!< Motorola AltiVec instructions - }; - - /** - * Returns true if the processor supports @p extension, - * and false otherwise. - * - * @param extension the feature to query. - * @return If true, the processor supports @p extension. - * @see Extensions - */ - static bool haveExtension( unsigned int extension ) - { return (s_features & extension) != 0; } - - private: - static unsigned int s_features; -}; - -#endif - diff --git a/kdefx/kdrawutil.cpp b/kdefx/kdrawutil.cpp deleted file mode 100644 index 83fe7d300..000000000 --- a/kdefx/kdrawutil.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Daniel M. Duley <mosfet@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 version 2 as published by the Free Software Foundation. - - 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#include "kdrawutil.h" -#include <tqdrawutil.h> - -KDEFX_EXPORT void kDrawNextButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken, - const TQBrush *fill) -{ - TQPen oldPen = p->pen(); - int x2 = x+w-1; - int y2 = y+h-1; - p->fillRect(x+1, y+1, w-2, h-2, - fill ? *fill : g.brush(TQColorGroup::Button)); - p->setPen(sunken ? Qt::black : g.light()); - p->drawLine(x, y, x2-1, y); - p->drawLine(x, y, x, y2-1); - p->setPen(sunken ? g.midlight() : g.mid()); - p->drawLine(x+1, y2-1, x2-1, y2-1); - p->drawLine(x2-1, y+1, x2-1, y2-1); - p->setPen(sunken ? g.light() : Qt::black); - p->drawLine(x, y2, x2, y2); - p->drawLine(x2, y, x2, y2); - p->setPen(oldPen); -} - - -KDEFX_EXPORT void kDrawNextButton(TQPainter *p, const TQRect &r, const TQColorGroup &g, - bool sunken, const TQBrush *fill) -{ - kDrawNextButton(p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill); -} - -KDEFX_EXPORT void kDrawBeButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken, const TQBrush *fill) -{ - TQPen oldPen = p->pen(); - int x2 = x+w-1; - int y2 = y+h-1; - p->setPen(g.dark()); - p->drawLine(x+1, y, x2-1, y); - p->drawLine(x, y+1, x, y2-1); - p->drawLine(x+1, y2, x2-1, y2); - p->drawLine(x2, y+1, x2, y2-1); - - - if(!sunken){ - p->setPen(g.light()); - p->drawLine(x+2, y+2, x2-1, y+2); - p->drawLine(x+2, y+3, x2-2, y+3); - p->drawLine(x+2, y+4, x+2, y2-1); - p->drawLine(x+3, y+4, x+3, y2-2); - } - else{ - p->setPen(g.mid()); - p->drawLine(x+2, y+2, x2-1, y+2); - p->drawLine(x+2, y+3, x2-2, y+3); - p->drawLine(x+2, y+4, x+2, y2-1); - p->drawLine(x+3, y+4, x+3, y2-2); - } - - - p->setPen(sunken? g.light() : g.mid()); - p->drawLine(x2-1, y+2, x2-1, y2-1); - p->drawLine(x+2, y2-1, x2-1, y2-1); - - p->setPen(g.mid()); - p->drawLine(x+1, y+1, x2-1, y+1); - p->drawLine(x+1, y+2, x+1, y2-1); - p->drawLine(x2-2, y+3, x2-2, y2-2); - - if(fill) - p->fillRect(x+4, y+4, w-6, h-6, *fill); - - p->setPen(oldPen); -} - -KDEFX_EXPORT void kDrawBeButton(TQPainter *p, TQRect &r, const TQColorGroup &g, bool sunken, - const TQBrush *fill) -{ - kDrawBeButton(p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill); -} - -KDEFX_EXPORT void kDrawRoundButton(TQPainter *p, const TQRect &r, const TQColorGroup &g, - bool sunken) -{ - int x, y, x2, y2; - r.coords(&x, &y, &x2, &y2); - if(r.width() > 16 && r.height() > 16){ - TQPen oldPen = p->pen(); - TQPointArray hPntArray, lPntArray; - hPntArray.putPoints(0, 12, x+4,y+1, x+5,y+1, // top left - x+3,y+2, x+2,y+3, x+1,y+4, x+1,y+5, - x+1,y2-5, x+1,y2-4, x+2,y2-3, // half corners - x2-5,y+1, x2-4,y+1, x2-3,y+2); - - lPntArray.putPoints(0, 17, x2-5,y2-1, x2-4,y2-1, // btm right - x2-3,y2-2, x2-2,y2-3, x2-1,y2-5, x2-1,y2-4, - - x+3,y2-2, x+4,y2-1, x+5,y2-1, //half corners - x2-2,y+3, x2-1,y+4, x2-1,y+5, - - x2-5,y2-2, x2-4,y2-2, // testing - x2-3,y2-3, - x2-2,y2-5, x2-2,y2-4); - - p->setPen(sunken ? g.dark() : g.light()); - p->drawLine(x+6, y, x2-6, y); - p->drawLine(0, y+6, 0, y2-6); - p->drawPoints(hPntArray); - - p->setPen(sunken ? g.light() : g.dark()); - p->drawLine(x+6, y2, x2-6, y2); - p->drawLine(x+6, y2-1, x2-6, y2-1); - p->drawLine(x2, y+6, x2, y2-6); - p->drawLine(x2-1, y+6, x2-1, y2-6); - p->drawPoints(lPntArray); - p->setPen(oldPen); - } - else - qDrawWinPanel(p, x, y, r.width(), r.height(), g, sunken); -} - -KDEFX_EXPORT void kDrawRoundButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken) -{ - TQRect r(x, y, w, h); - kDrawRoundButton(p, r, g, sunken); -} - -#define QCOORDARRLEN(x) sizeof(x)/(sizeof(TQCOORD)*2) - -KDEFX_EXPORT void kDrawRoundMask(TQPainter *p, int x, int y, int w, int h, bool clear) -{ - // round edge fills - static const TQCOORD btm_left_fill[]={ 0,0,1,0,2,0,3,0,4,0,0,1,1,1,2,1,3,1,4,1, - 1,2,2,2,3,2,4,2,2,3,3,3,4,3,3,4,4,4 }; - - static const TQCOORD btm_right_fill[]={ 0,0,1,0,2,0,3,0,4,0,0,1,1,1,2,1,3,1,4, - 1,0,2,1,2,2,2,3,2,0,3,1,3,2,3,0,4,1,4 }; - - static const TQCOORD top_left_fill[]={ 3,0,4,0,2,1,3,1,4,1,1,2,2,2,3,2,4,2,0,3, - 1,3,2,3,3,3,4,3,0,4,1,4,2,4,3,4,4,4 }; - - static const TQCOORD top_right_fill[]={ 0,0,1,0,0,1,1,1,2,1,0,2,1,2,2,2,3,2,0, - 3,1,3,2,3,3,3,4,3,0,4,1,4,2,4,3,4,4,4 }; - - if(clear) - p->fillRect(x, y, w, h, TQBrush(Qt::color0, Qt::SolidPattern)); - - TQBrush fillBrush(Qt::color1, Qt::SolidPattern); - p->setPen(Qt::color1); - if(w > 16 && h > 16){ - int x2 = x+w-1; - int y2 = y+h-1; - TQPointArray a(QCOORDARRLEN(top_left_fill), top_left_fill); - a.translate(1, 1); - p->drawPoints(a); - a.setPoints(QCOORDARRLEN(btm_left_fill), btm_left_fill); - a.translate(1, h-6); - p->drawPoints(a); - a.setPoints(QCOORDARRLEN(top_right_fill), top_right_fill); - a.translate(w-6, 1); - p->drawPoints(a); - a.setPoints(QCOORDARRLEN(btm_right_fill), btm_right_fill); - a.translate(w-6, h-6); - p->drawPoints(a); - - p->fillRect(x+6, y, w-12, h, fillBrush); - p->fillRect(x, y+6, x+6, h-12, fillBrush); - p->fillRect(x2-6, y+6, x2, h-12, fillBrush); - p->drawLine(x+6, y, x2-6, y); - p->drawLine(x+6, y2, x2-6, y2); - p->drawLine(x, y+6, x, y2-6); - p->drawLine(x2, y+6, x2, y2-6); - - } - else - p->fillRect(x, y, w, h, fillBrush); -} - -KDEFX_EXPORT void kRoundMaskRegion(TQRegion &r, int x, int y, int w, int h) -{ - // using a bunch of TQRect lines seems much more efficient than bitmaps or - // point arrays, even tho it uses more statements - r += TQRect(x+6, y+0, w-12, h); - r += TQRect(x+5, y+1, 1, h-2); // left - r += TQRect(x+4, y+1, 1, h-2); - r += TQRect(x+3, y+2, 1, h-4); - r += TQRect(x+2, y+3, 1, h-6); - r += TQRect(x+1, y+4, 1, h-8); - r += TQRect(x, y+6, 1, h-12); - int x2 = x+w-1; - r += TQRect(x2-5, y+1, 1, h-2); // right - r += TQRect(x2-4, y+1, 1, h-2); - r += TQRect(x2-3, y+2, 1, h-4); - r += TQRect(x2-2, y+3, 1, h-6); - r += TQRect(x2-1, y+4, 1, h-8); - r += TQRect(x2, y+6, 1, h-12); -} - -KDEFX_EXPORT void kColorBitmaps(TQPainter *p, const TQColorGroup &g, int x, int y, - TQBitmap *lightColor, TQBitmap *midColor, - TQBitmap *midlightColor, TQBitmap *darkColor, - TQBitmap *blackColor, TQBitmap *whiteColor) -{ - TQBitmap *bitmaps[]={lightColor, midColor, midlightColor, darkColor, - blackColor, whiteColor}; - - TQColor colors[]={g.light(), g.mid(), g.midlight(), g.dark(), - Qt::black, Qt::white}; - - int i; - for(i=0; i < 6; ++i){ - if(bitmaps[i]){ - if(!bitmaps[i]->mask()) - bitmaps[i]->setMask(*bitmaps[i]); - p->setPen(colors[i]); - p->drawPixmap(x, y, *bitmaps[i]); - } - } -} - -KDEFX_EXPORT void kColorBitmaps(TQPainter *p, const TQColorGroup &g, int x, int y, int w, - int h, bool isXBitmaps, const uchar *lightColor, - const uchar *midColor, const uchar *midlightColor, - const uchar *darkColor, const uchar *blackColor, - const uchar *whiteColor) -{ - const uchar *data[]={lightColor, midColor, midlightColor, darkColor, - blackColor, whiteColor}; - - TQColor colors[]={g.light(), g.mid(), g.midlight(), g.dark(), - Qt::black, Qt::white}; - - int i; - TQBitmap b; - for(i=0; i < 6; ++i){ - if(data[i]){ - b = TQBitmap(w, h, data[i], isXBitmaps); - b.setMask(b); - p->setPen(colors[i]); - p->drawPixmap(x, y, b); - } - } -} - - - diff --git a/kdefx/kdrawutil.h b/kdefx/kdrawutil.h deleted file mode 100644 index 6aa0f3c44..000000000 --- a/kdefx/kdrawutil.h +++ /dev/null @@ -1,180 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Daniel M. Duley <mosfet@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 version 2 as published by the Free Software Foundation. - - 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ -#ifndef __KDRAWUTIL_H -#define __KDRAWUTIL_H - -#include <tqnamespace.h> -#include <tqpainter.h> -#include <tqbitmap.h> -#include <tqpalette.h> - -#include <kdelibs_export.h> - -/* - * Various drawing routines. Also see Qt's tqdrawutil.h for some more routines - * contained in Qt. - * - * (C) Daniel M. Duley <mosfet@kde.org> - */ - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Draws a Next-style button (solid black shadow with light and midlight highlight). - * - * @param p The painter to use for drawing the button. - * @param r Specifies the rect in which to draw the button. - * @param g Specifies the shading colors. - * @param sunken Whether to draw the button as sunken (pressed) or not. - * @param fill The brush to use for filling the interior of the button. - * Pass @a null to prevent the button from being filled. - */ -KDEFX_EXPORT void kDrawNextButton(TQPainter *p, const TQRect &r, const TQColorGroup &g, - bool sunken=false, const TQBrush *fill=0); - -/** - * @relates KStyle - * @overload - */ -KDEFX_EXPORT void kDrawNextButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken=false, - const TQBrush *fill=0); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Draws a Be-style button. - * - * @param p The painter to use for drawing the button. - * @param r Specifies the rect in which to draw the button. - * @param g Specifies the shading colors. - * @param sunken Whether to draw the button as sunken (pressed) or not. - * @param fill The brush to use for filling the interior of the button. - * Pass @a null to prevent the button from being filled. - */ -KDEFX_EXPORT void kDrawBeButton(TQPainter *p, TQRect &r, const TQColorGroup &g, - bool sunken=false, const TQBrush *fill=0); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * @overload - */ -KDEFX_EXPORT void kDrawBeButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken=false, - const TQBrush *fill=0); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Draws a rounded oval button. This function doesn't fill the button. - * See kRoundMaskRegion() for setting masks for fills. - * - * @param p The painter to use for drawing the button. - * @param r Specifies the rect in which to draw the button. - * @param g Specifies the shading colors. - * @param sunken Whether to draw the button as sunken (pressed) or not. - */ -KDEFX_EXPORT void kDrawRoundButton(TQPainter *p, const TQRect &r, const TQColorGroup &g, - bool sunken=false); - -/** - * @relates KStyle - * @overload - */ -KDEFX_EXPORT void kDrawRoundButton(TQPainter *p, int x, int y, int w, int h, - const TQColorGroup &g, bool sunken=false); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Sets a region to the pixels covered by a round button of the given - * size. You can use this to set clipping regions. - * - * @param r Reference to the region to set. - * @param x The X coordinate of the button. - * @param y The Y coordinate of the button. - * @param w The width of the button. - * @param h The height of the button. - * - * @see kDrawRoundButton() and kDrawRoundMask() - */ -KDEFX_EXPORT void kRoundMaskRegion(TQRegion &r, int x, int y, int w, int h); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Paints the pixels covered by a round button of the given size with - * Qt::color1. This function is useful in TQStyle::tqdrawControlMask(). - * - * @param p The painter to use for drawing the button. - * @param x The X coordinate of the button. - * @param y The Y coordinate of the button. - * @param w The width of the button. - * @param h The height of the button. - * @param clear Whether to clear the rectangle specified by @p (x, y, w, h) to - * Qt::color0 before drawing the mask. - */ -KDEFX_EXPORT void kDrawRoundMask(TQPainter *p, int x, int y, int w, int h, bool clear=false); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * - * Paints the provided bitmaps in the painter, using the supplied colorgroup for - * the foreground colors. There's one bitmap for each color. If you want to skip - * a color, pass @a null for the corresponding bitmap. - * - * @note The bitmaps will be self-masked automatically if not masked - * prior to calling this routine. - * - * @param p The painter to use for drawing the bitmaps. - * @param g Specifies the shading colors. - * @param x The X coordinate at which to draw the bitmaps. - * @param y The Y coordinate at which to draw the bitmaps. - * @param lightColor The bitmap to use for the light part. - * @param midColor The bitmap to use for the mid part. - * @param midlightColor The bitmap to use for the midlight part. - * @param darkColor The bitmap to use for the dark part. - * @param blackColor The bitmap to use for the black part. - * @param whiteColor The bitmap to use for the white part. - * - * @see QColorGroup - */ -KDEFX_EXPORT void kColorBitmaps(TQPainter *p, const TQColorGroup &g, int x, int y, - TQBitmap *lightColor=0, TQBitmap *midColor=0, - TQBitmap *midlightColor=0, TQBitmap *darkColor=0, - TQBitmap *blackColor=0, TQBitmap *whiteColor=0); - -/** - * @relates KStyle - * @c \#include @c <kdrawutil.h> - * @overload - */ - KDEFX_EXPORT void kColorBitmaps(TQPainter *p, const TQColorGroup &g, int x, int y, int w, - int h, bool isXBitmaps=true, const uchar *lightColor = 0, - const uchar *midColor=0, const uchar *midlightColor=0, - const uchar *darkColor=0, const uchar *blackColor=0, - const uchar *whiteColor=0); - -#endif diff --git a/kdefx/kimageeffect.cpp b/kdefx/kimageeffect.cpp deleted file mode 100644 index d2955403a..000000000 --- a/kdefx/kimageeffect.cpp +++ /dev/null @@ -1,4980 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@kde.org> - (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> - (C) 1998, 1999 Dirk Mueller <mueller@kde.org> - (C) 1999 Geert Jansen <g.t.jansen@stud.tue.nl> - (C) 2000 Josef Weidendorfer <weidendo@in.tum.de> - (C) 2004 Zack Rusin <zack@kde.org> - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -// $Id$ - -#include <math.h> -#include <assert.h> - -#include <tqimage.h> -#include <stdlib.h> -#include <iostream> - -#include "kimageeffect.h" -#include "kcpuinfo.h" - -#include <config.h> - -#if 0 -//disabled until #74478 fixed. - -#if defined(__i386__) && ( defined(__GNUC__) || defined(__INTEL_COMPILER) ) -# if defined( HAVE_X86_MMX ) -# define USE_MMX_INLINE_ASM -# endif -# if defined( HAVE_X86_SSE2 ) -# define USE_SSE2_INLINE_ASM -# endif -#endif - -#endif -//====================================================================== -// -// Utility stuff for effects ported from ImageMagick to QImage -// -//====================================================================== -#define MaxRGB 255L -#define DegreesToRadians(x) ((x)*M_PI/180.0) -#define MagickSQ2PI 2.50662827463100024161235523934010416269302368164062 -#define MagickEpsilon 1.0e-12 -#define MagickPI 3.14159265358979323846264338327950288419716939937510 -#define MOD(x, y) ((x) < 0 ? ((y) - 1 - ((y) - 1 - (x)) % (y)) : (x) % (y)) - -/** - * \relates KGlobal - * A typesafe function that returns x if it's between low and high values. - * low if x is smaller than then low and high if x is bigger than high. - */ -#define FXCLAMP(x,low,high) fxClamp(x,low,high) -template<class T> -inline const T& fxClamp( const T& x, const T& low, const T& high ) -{ - if ( x < low ) return low; - else if ( x > high ) return high; - else return x; -} - -static inline unsigned int intensityValue(unsigned int color) -{ - return((unsigned int)((0.299*tqRed(color) + - 0.587*tqGreen(color) + - 0.1140000000000001*tqBlue(color)))); -} - -template<typename T> -static inline void liberateMemory(T **memory) -{ - assert(memory != NULL); - if(*memory == NULL) return; - free((char*)*memory); - *memory=NULL; -} - -struct double_packet -{ - double red; - double green; - double blue; - double alpha; -}; - -struct short_packet -{ - unsigned short int red; - unsigned short int green; - unsigned short int blue; - unsigned short int alpha; -}; - - -//====================================================================== -// -// Gradient effects -// -//====================================================================== - -TQImage KImageEffect::gradient(const TQSize &size, const TQColor &ca, - const TQColor &cb, GradientType eff, int ncols) -{ - int rDiff, gDiff, bDiff; - int rca, gca, bca, rcb, gcb, bcb; - - TQImage image(size, 32); - - if (size.width() == 0 || size.height() == 0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::gradient: invalid image" << std::endl; -#endif - return image; - } - - register int x, y; - - rDiff = (rcb = cb.red()) - (rca = ca.red()); - gDiff = (gcb = cb.green()) - (gca = ca.green()); - bDiff = (bcb = cb.blue()) - (bca = ca.blue()); - - if( eff == VerticalGradient || eff == HorizontalGradient ){ - - uint *p; - uint rgb; - - register int rl = rca << 16; - register int gl = gca << 16; - register int bl = bca << 16; - - if( eff == VerticalGradient ) { - - int rcdelta = ((1<<16) / size.height()) * rDiff; - int gcdelta = ((1<<16) / size.height()) * gDiff; - int bcdelta = ((1<<16) / size.height()) * bDiff; - - for ( y = 0; y < size.height(); y++ ) { - p = (uint *) image.scanLine(y); - - rl += rcdelta; - gl += gcdelta; - bl += bcdelta; - - rgb = tqRgb( (rl>>16), (gl>>16), (bl>>16) ); - - for( x = 0; x < size.width(); x++ ) { - *p = rgb; - p++; - } - } - - } - else { // must be HorizontalGradient - - unsigned int *o_src = (unsigned int *)image.scanLine(0); - unsigned int *src = o_src; - - int rcdelta = ((1<<16) / size.width()) * rDiff; - int gcdelta = ((1<<16) / size.width()) * gDiff; - int bcdelta = ((1<<16) / size.width()) * bDiff; - - for( x = 0; x < size.width(); x++) { - - rl += rcdelta; - gl += gcdelta; - bl += bcdelta; - - *src++ = tqRgb( (rl>>16), (gl>>16), (bl>>16)); - } - - src = o_src; - - // Believe it or not, manually copying in a for loop is faster - // than calling memcpy for each scanline (on the order of ms...). - // I think this is due to the function call overhead (mosfet). - - for (y = 1; y < size.height(); ++y) { - - p = (unsigned int *)image.scanLine(y); - src = o_src; - for(x=0; x < size.width(); ++x) - *p++ = *src++; - } - } - } - - else { - - float rfd, gfd, bfd; - float rd = rca, gd = gca, bd = bca; - - unsigned char *xtable[3]; - unsigned char *ytable[3]; - - unsigned int w = size.width(), h = size.height(); - xtable[0] = new unsigned char[w]; - xtable[1] = new unsigned char[w]; - xtable[2] = new unsigned char[w]; - ytable[0] = new unsigned char[h]; - ytable[1] = new unsigned char[h]; - ytable[2] = new unsigned char[h]; - w*=2, h*=2; - - if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) { - // Diagonal dgradient code inspired by BlackBox (mosfet) - // BlackBox dgradient is (C) Brad Hughes, <bhughes@tcac.net> and - // Mike Cole <mike@mydot.com>. - - rfd = (float)rDiff/w; - gfd = (float)gDiff/w; - bfd = (float)bDiff/w; - - int dir; - for (x = 0; x < size.width(); x++, rd+=rfd, gd+=gfd, bd+=bfd) { - dir = eff == DiagonalGradient? x : size.width() - x - 1; - xtable[0][dir] = (unsigned char) rd; - xtable[1][dir] = (unsigned char) gd; - xtable[2][dir] = (unsigned char) bd; - } - rfd = (float)rDiff/h; - gfd = (float)gDiff/h; - bfd = (float)bDiff/h; - rd = gd = bd = 0; - for (y = 0; y < size.height(); y++, rd+=rfd, gd+=gfd, bd+=bfd) { - ytable[0][y] = (unsigned char) rd; - ytable[1][y] = (unsigned char) gd; - ytable[2][y] = (unsigned char) bd; - } - - for (y = 0; y < size.height(); y++) { - unsigned int *scanline = (unsigned int *)image.scanLine(y); - for (x = 0; x < size.width(); x++) { - scanline[x] = tqRgb(xtable[0][x] + ytable[0][y], - xtable[1][x] + ytable[1][y], - xtable[2][x] + ytable[2][y]); - } - } - } - - else if (eff == RectangleGradient || - eff == PyramidGradient || - eff == PipeCrossGradient || - eff == EllipticGradient) - { - int rSign = rDiff>0? 1: -1; - int gSign = gDiff>0? 1: -1; - int bSign = bDiff>0? 1: -1; - - rfd = (float)rDiff / size.width(); - gfd = (float)gDiff / size.width(); - bfd = (float)bDiff / size.width(); - - rd = (float)rDiff/2; - gd = (float)gDiff/2; - bd = (float)bDiff/2; - - for (x = 0; x < size.width(); x++, rd-=rfd, gd-=gfd, bd-=bfd) - { - xtable[0][x] = (unsigned char) abs((int)rd); - xtable[1][x] = (unsigned char) abs((int)gd); - xtable[2][x] = (unsigned char) abs((int)bd); - } - - rfd = (float)rDiff/size.height(); - gfd = (float)gDiff/size.height(); - bfd = (float)bDiff/size.height(); - - rd = (float)rDiff/2; - gd = (float)gDiff/2; - bd = (float)bDiff/2; - - for (y = 0; y < size.height(); y++, rd-=rfd, gd-=gfd, bd-=bfd) - { - ytable[0][y] = (unsigned char) abs((int)rd); - ytable[1][y] = (unsigned char) abs((int)gd); - ytable[2][y] = (unsigned char) abs((int)bd); - } - - int h = (size.height()+1)>>1; - for (y = 0; y < h; y++) { - unsigned int *sl1 = (unsigned int *)image.scanLine(y); - unsigned int *sl2 = (unsigned int *)image.scanLine(QMAX(size.height()-y-1, y)); - - int w = (size.width()+1)>>1; - int x2 = size.width()-1; - - for (x = 0; x < w; x++, x2--) { - unsigned int rgb = 0; - if (eff == PyramidGradient) { - rgb = tqRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), - gcb-gSign*(xtable[1][x]+ytable[1][y]), - bcb-bSign*(xtable[2][x]+ytable[2][y])); - } - if (eff == RectangleGradient) { - rgb = tqRgb(rcb - rSign * - QMAX(xtable[0][x], ytable[0][y]) * 2, - gcb - gSign * - QMAX(xtable[1][x], ytable[1][y]) * 2, - bcb - bSign * - QMAX(xtable[2][x], ytable[2][y]) * 2); - } - if (eff == PipeCrossGradient) { - rgb = tqRgb(rcb - rSign * - QMIN(xtable[0][x], ytable[0][y]) * 2, - gcb - gSign * - QMIN(xtable[1][x], ytable[1][y]) * 2, - bcb - bSign * - QMIN(xtable[2][x], ytable[2][y]) * 2); - } - if (eff == EllipticGradient) { - rgb = tqRgb(rcb - rSign * - (int)sqrt((xtable[0][x]*xtable[0][x] + - ytable[0][y]*ytable[0][y])*2.0), - gcb - gSign * - (int)sqrt((xtable[1][x]*xtable[1][x] + - ytable[1][y]*ytable[1][y])*2.0), - bcb - bSign * - (int)sqrt((xtable[2][x]*xtable[2][x] + - ytable[2][y]*ytable[2][y])*2.0)); - } - - sl1[x] = sl2[x] = rgb; - sl1[x2] = sl2[x2] = rgb; - } - } - } - - delete [] xtable[0]; - delete [] xtable[1]; - delete [] xtable[2]; - delete [] ytable[0]; - delete [] ytable[1]; - delete [] ytable[2]; - } - - // dither if necessary - if (ncols && (TQPixmap::defaultDepth() < 15 )) { - if ( ncols < 2 || ncols > 256 ) - ncols = 3; - TQColor *dPal = new TQColor[ncols]; - for (int i=0; i<ncols; i++) { - dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), - gca + gDiff * i / ( ncols - 1 ), - bca + bDiff * i / ( ncols - 1 ) ); - } - dither(image, dPal, ncols); - delete [] dPal; - } - - return image; -} - - -// ----------------------------------------------------------------------------- - -//CT this was (before Dirk A. Mueller's speedup changes) -// merely the same code as in the above method, but it's supposedly -// way less performant since it introduces a lot of supplementary tests -// and simple math operations for the calculus of the balance. -// (surprizingly, it isn't less performant, in the contrary :-) -// Yes, I could have merged them, but then the excellent performance of -// the balanced code would suffer with no other gain than a mere -// source code and byte code size economy. - -TQImage KImageEffect::unbalancedGradient(const TQSize &size, const TQColor &ca, - const TQColor &cb, GradientType eff, int xfactor, int yfactor, - int ncols) -{ - int dir; // general parameter used for direction switches - - bool _xanti = false , _yanti = false; - - if (xfactor < 0) _xanti = true; // negative on X direction - if (yfactor < 0) _yanti = true; // negative on Y direction - - xfactor = abs(xfactor); - yfactor = abs(yfactor); - - if (!xfactor) xfactor = 1; - if (!yfactor) yfactor = 1; - - if (xfactor > 200 ) xfactor = 200; - if (yfactor > 200 ) yfactor = 200; - - - // float xbal = xfactor/5000.; - // float ybal = yfactor/5000.; - float xbal = xfactor/30./size.width(); - float ybal = yfactor/30./size.height(); - float rat; - - int rDiff, gDiff, bDiff; - int rca, gca, bca, rcb, gcb, bcb; - - TQImage image(size, 32); - - if (size.width() == 0 || size.height() == 0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::unbalancedGradient : invalid image\n"; -#endif - return image; - } - - register int x, y; - unsigned int *scanline; - - rDiff = (rcb = cb.red()) - (rca = ca.red()); - gDiff = (gcb = cb.green()) - (gca = ca.green()); - bDiff = (bcb = cb.blue()) - (bca = ca.blue()); - - if( eff == VerticalGradient || eff == HorizontalGradient){ - TQColor cRow; - - uint *p; - uint rgbRow; - - if( eff == VerticalGradient) { - for ( y = 0; y < size.height(); y++ ) { - dir = _yanti ? y : size.height() - 1 - y; - p = (uint *) image.scanLine(dir); - rat = 1 - exp( - (float)y * ybal ); - - cRow.setRgb( rcb - (int) ( rDiff * rat ), - gcb - (int) ( gDiff * rat ), - bcb - (int) ( bDiff * rat ) ); - - rgbRow = cRow.rgb(); - - for( x = 0; x < size.width(); x++ ) { - *p = rgbRow; - p++; - } - } - } - else { - - unsigned int *src = (unsigned int *)image.scanLine(0); - for(x = 0; x < size.width(); x++ ) - { - dir = _xanti ? x : size.width() - 1 - x; - rat = 1 - exp( - (float)x * xbal ); - - src[dir] = tqRgb(rcb - (int) ( rDiff * rat ), - gcb - (int) ( gDiff * rat ), - bcb - (int) ( bDiff * rat )); - } - - // Believe it or not, manually copying in a for loop is faster - // than calling memcpy for each scanline (on the order of ms...). - // I think this is due to the function call overhead (mosfet). - - for(y = 1; y < size.height(); ++y) - { - scanline = (unsigned int *)image.scanLine(y); - for(x=0; x < size.width(); ++x) - scanline[x] = src[x]; - } - } - } - - else { - int w=size.width(), h=size.height(); - - unsigned char *xtable[3]; - unsigned char *ytable[3]; - xtable[0] = new unsigned char[w]; - xtable[1] = new unsigned char[w]; - xtable[2] = new unsigned char[w]; - ytable[0] = new unsigned char[h]; - ytable[1] = new unsigned char[h]; - ytable[2] = new unsigned char[h]; - - if ( eff == DiagonalGradient || eff == CrossDiagonalGradient) - { - for (x = 0; x < w; x++) { - dir = _xanti ? x : w - 1 - x; - rat = 1 - exp( - (float)x * xbal ); - - xtable[0][dir] = (unsigned char) ( rDiff/2 * rat ); - xtable[1][dir] = (unsigned char) ( gDiff/2 * rat ); - xtable[2][dir] = (unsigned char) ( bDiff/2 * rat ); - } - - for (y = 0; y < h; y++) { - dir = _yanti ? y : h - 1 - y; - rat = 1 - exp( - (float)y * ybal ); - - ytable[0][dir] = (unsigned char) ( rDiff/2 * rat ); - ytable[1][dir] = (unsigned char) ( gDiff/2 * rat ); - ytable[2][dir] = (unsigned char) ( bDiff/2 * rat ); - } - - for (y = 0; y < h; y++) { - unsigned int *scanline = (unsigned int *)image.scanLine(y); - for (x = 0; x < w; x++) { - scanline[x] = tqRgb(rcb - (xtable[0][x] + ytable[0][y]), - gcb - (xtable[1][x] + ytable[1][y]), - bcb - (xtable[2][x] + ytable[2][y])); - } - } - } - - else if (eff == RectangleGradient || - eff == PyramidGradient || - eff == PipeCrossGradient || - eff == EllipticGradient) - { - int rSign = rDiff>0? 1: -1; - int gSign = gDiff>0? 1: -1; - int bSign = bDiff>0? 1: -1; - - for (x = 0; x < w; x++) - { - dir = _xanti ? x : w - 1 - x; - rat = 1 - exp( - (float)x * xbal ); - - xtable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); - xtable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); - xtable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); - } - - for (y = 0; y < h; y++) - { - dir = _yanti ? y : h - 1 - y; - - rat = 1 - exp( - (float)y * ybal ); - - ytable[0][dir] = (unsigned char) abs((int)(rDiff*(0.5-rat))); - ytable[1][dir] = (unsigned char) abs((int)(gDiff*(0.5-rat))); - ytable[2][dir] = (unsigned char) abs((int)(bDiff*(0.5-rat))); - } - - for (y = 0; y < h; y++) { - unsigned int *scanline = (unsigned int *)image.scanLine(y); - for (x = 0; x < w; x++) { - if (eff == PyramidGradient) - { - scanline[x] = tqRgb(rcb-rSign*(xtable[0][x]+ytable[0][y]), - gcb-gSign*(xtable[1][x]+ytable[1][y]), - bcb-bSign*(xtable[2][x]+ytable[2][y])); - } - else if (eff == RectangleGradient) - { - scanline[x] = tqRgb(rcb - rSign * - QMAX(xtable[0][x], ytable[0][y]) * 2, - gcb - gSign * - QMAX(xtable[1][x], ytable[1][y]) * 2, - bcb - bSign * - QMAX(xtable[2][x], ytable[2][y]) * 2); - } - else if (eff == PipeCrossGradient) - { - scanline[x] = tqRgb(rcb - rSign * - QMIN(xtable[0][x], ytable[0][y]) * 2, - gcb - gSign * - QMIN(xtable[1][x], ytable[1][y]) * 2, - bcb - bSign * - QMIN(xtable[2][x], ytable[2][y]) * 2); - } - else if (eff == EllipticGradient) - { - scanline[x] = tqRgb(rcb - rSign * - (int)sqrt((xtable[0][x]*xtable[0][x] + - ytable[0][y]*ytable[0][y])*2.0), - gcb - gSign * - (int)sqrt((xtable[1][x]*xtable[1][x] + - ytable[1][y]*ytable[1][y])*2.0), - bcb - bSign * - (int)sqrt((xtable[2][x]*xtable[2][x] + - ytable[2][y]*ytable[2][y])*2.0)); - } - } - } - } - - if (ncols && (TQPixmap::defaultDepth() < 15 )) { - if ( ncols < 2 || ncols > 256 ) - ncols = 3; - TQColor *dPal = new TQColor[ncols]; - for (int i=0; i<ncols; i++) { - dPal[i].setRgb ( rca + rDiff * i / ( ncols - 1 ), - gca + gDiff * i / ( ncols - 1 ), - bca + bDiff * i / ( ncols - 1 ) ); - } - dither(image, dPal, ncols); - delete [] dPal; - } - - delete [] xtable[0]; - delete [] xtable[1]; - delete [] xtable[2]; - delete [] ytable[0]; - delete [] ytable[1]; - delete [] ytable[2]; - - } - - return image; -} - -/** -Types for MMX and SSE packing of colors, for safe constraints -*/ -namespace { - -struct KIE4Pack -{ - TQ_UINT16 data[4]; -}; - -struct KIE8Pack -{ - TQ_UINT16 data[8]; -}; - -} - -//====================================================================== -// -// Intensity effects -// -//====================================================================== - - -/* This builds a 256 byte unsigned char lookup table with all - * the possible percent values prior to applying the effect, then uses - * integer math for the pixels. For any image larger than 9x9 this will be - * less expensive than doing a float operation on the 3 color components of - * each pixel. (mosfet) - */ -TQImage& KImageEffect::intensity(TQImage &image, float percent) -{ - if (image.width() == 0 || image.height() == 0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::intensity : invalid image\n"; -#endif - return image; - } - - int segColors = image.depth() > 8 ? 256 : image.numColors(); - int pixels = image.depth() > 8 ? image.width()*image.height() : - image.numColors(); - unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : - (unsigned int *)image.tqcolorTable(); - - bool brighten = (percent >= 0); - if(percent < 0) - percent = -percent; - -#ifdef USE_MMX_INLINE_ASM - bool haveMMX = KCPUInfo::haveExtension( KCPUInfo::IntelMMX ); - - if(haveMMX) - { - TQ_UINT16 p = TQ_UINT16(256.0f*(percent)); - KIE4Pack mult = {{p,p,p,0}}; - - __asm__ __volatile__( - "pxor %%mm7, %%mm7\n\t" // zero mm7 for unpacking - "movq (%0), %%mm6\n\t" // copy intensity change to mm6 - : : "r"(&mult), "m"(mult)); - - unsigned int rem = pixels % 4; - pixels -= rem; - TQ_UINT32 *end = ( data + pixels ); - - if (brighten) - { - while ( data != end ) { - __asm__ __volatile__( - "movq (%0), %%mm0\n\t" - "movq 8(%0), %%mm4\n\t" // copy 4 pixels of data to mm0 and mm4 - "movq %%mm0, %%mm1\n\t" - "movq %%mm0, %%mm3\n\t" - "movq %%mm4, %%mm5\n\t" // copy to registers for unpacking - "punpcklbw %%mm7, %%mm0\n\t" - "punpckhbw %%mm7, %%mm1\n\t" // unpack the two pixels from mm0 - "pmullw %%mm6, %%mm0\n\t" - "punpcklbw %%mm7, %%mm4\n\t" - "pmullw %%mm6, %%mm1\n\t" // multiply by intensity*256 - "psrlw $8, %%mm0\n\t" // divide by 256 - "pmullw %%mm6, %%mm4\n\t" - "psrlw $8, %%mm1\n\t" - "psrlw $8, %%mm4\n\t" - "packuswb %%mm1, %%mm0\n\t" // pack solution into mm0. saturates at 255 - "movq %%mm5, %%mm1\n\t" - - "punpckhbw %%mm7, %%mm1\n\t" // unpack 4th pixel in mm1 - - "pmullw %%mm6, %%mm1\n\t" - "paddusb %%mm3, %%mm0\n\t" // add intesity result to original of mm0 - "psrlw $8, %%mm1\n\t" - "packuswb %%mm1, %%mm4\n\t" // pack upper two pixels into mm4 - - "movq %%mm0, (%0)\n\t" // rewrite to memory lower two pixels - "paddusb %%mm5, %%mm4\n\t" - "movq %%mm4, 8(%0)\n\t" // rewrite upper two pixels - : : "r"(data) ); - data += 4; - } - - end += rem; - while ( data != end ) { - __asm__ __volatile__( - "movd (%0), %%mm0\n\t" // repeat above but for - "punpcklbw %%mm7, %%mm0\n\t" // one pixel at a time - "movq %%mm0, %%mm3\n\t" - "pmullw %%mm6, %%mm0\n\t" - "psrlw $8, %%mm0\n\t" - "paddw %%mm3, %%mm0\n\t" - "packuswb %%mm0, %%mm0\n\t" - "movd %%mm0, (%0)\n\t" - : : "r"(data) ); - data++; - } - } - else - { - while ( data != end ) { - __asm__ __volatile__( - "movq (%0), %%mm0\n\t" - "movq 8(%0), %%mm4\n\t" - "movq %%mm0, %%mm1\n\t" - "movq %%mm0, %%mm3\n\t" - - "movq %%mm4, %%mm5\n\t" - - "punpcklbw %%mm7, %%mm0\n\t" - "punpckhbw %%mm7, %%mm1\n\t" - "pmullw %%mm6, %%mm0\n\t" - "punpcklbw %%mm7, %%mm4\n\t" - "pmullw %%mm6, %%mm1\n\t" - "psrlw $8, %%mm0\n\t" - "pmullw %%mm6, %%mm4\n\t" - "psrlw $8, %%mm1\n\t" - "psrlw $8, %%mm4\n\t" - "packuswb %%mm1, %%mm0\n\t" - "movq %%mm5, %%mm1\n\t" - - "punpckhbw %%mm7, %%mm1\n\t" - - "pmullw %%mm6, %%mm1\n\t" - "psubusb %%mm0, %%mm3\n\t" // subtract darkening amount - "psrlw $8, %%mm1\n\t" - "packuswb %%mm1, %%mm4\n\t" - - "movq %%mm3, (%0)\n\t" - "psubusb %%mm4, %%mm5\n\t" // only change for this version is - "movq %%mm5, 8(%0)\n\t" // subtraction here as we are darkening image - : : "r"(data) ); - data += 4; - } - - end += rem; - while ( data != end ) { - __asm__ __volatile__( - "movd (%0), %%mm0\n\t" - "punpcklbw %%mm7, %%mm0\n\t" - "movq %%mm0, %%mm3\n\t" - "pmullw %%mm6, %%mm0\n\t" - "psrlw $8, %%mm0\n\t" - "psubusw %%mm0, %%mm3\n\t" - "packuswb %%mm3, %%mm3\n\t" - "movd %%mm3, (%0)\n\t" - : : "r"(data) ); - data++; - } - } - __asm__ __volatile__("emms"); // clear mmx state - } - else -#endif // USE_MMX_INLINE_ASM - { - unsigned char *segTbl = new unsigned char[segColors]; - int tmp; - if(brighten){ // keep overflow check out of loops - for(int i=0; i < segColors; ++i){ - tmp = (int)(i*percent); - if(tmp > 255) - tmp = 255; - segTbl[i] = tmp; - } - } - else{ - for(int i=0; i < segColors; ++i){ - tmp = (int)(i*percent); - if(tmp < 0) - tmp = 0; - segTbl[i] = tmp; - } - } - - if(brighten){ // same here - for(int i=0; i < pixels; ++i){ - int r = tqRed(data[i]); - int g = tqGreen(data[i]); - int b = tqBlue(data[i]); - int a = tqAlpha(data[i]); - r = r + segTbl[r] > 255 ? 255 : r + segTbl[r]; - g = g + segTbl[g] > 255 ? 255 : g + segTbl[g]; - b = b + segTbl[b] > 255 ? 255 : b + segTbl[b]; - data[i] = tqRgba(r, g, b,a); - } - } - else{ - for(int i=0; i < pixels; ++i){ - int r = tqRed(data[i]); - int g = tqGreen(data[i]); - int b = tqBlue(data[i]); - int a = tqAlpha(data[i]); - r = r - segTbl[r] < 0 ? 0 : r - segTbl[r]; - g = g - segTbl[g] < 0 ? 0 : g - segTbl[g]; - b = b - segTbl[b] < 0 ? 0 : b - segTbl[b]; - data[i] = tqRgba(r, g, b, a); - } - } - delete [] segTbl; - } - - return image; -} - -TQImage& KImageEffect::channelIntensity(TQImage &image, float percent, - RGBComponent channel) -{ - if (image.width() == 0 || image.height() == 0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::channelIntensity : invalid image\n"; -#endif - return image; - } - - int segColors = image.depth() > 8 ? 256 : image.numColors(); - unsigned char *segTbl = new unsigned char[segColors]; - int pixels = image.depth() > 8 ? image.width()*image.height() : - image.numColors(); - unsigned int *data = image.depth() > 8 ? (unsigned int *)image.bits() : - (unsigned int *)image.tqcolorTable(); - bool brighten = (percent >= 0); - if(percent < 0) - percent = -percent; - - if(brighten){ // keep overflow check out of loops - for(int i=0; i < segColors; ++i){ - int tmp = (int)(i*percent); - if(tmp > 255) - tmp = 255; - segTbl[i] = tmp; - } - } - else{ - for(int i=0; i < segColors; ++i){ - int tmp = (int)(i*percent); - if(tmp < 0) - tmp = 0; - segTbl[i] = tmp; - } - } - - if(brighten){ // same here - if(channel == Red){ // and here ;-) - for(int i=0; i < pixels; ++i){ - int c = tqRed(data[i]); - c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; - data[i] = tqRgba(c, tqGreen(data[i]), tqBlue(data[i]), tqAlpha(data[i])); - } - } - else if(channel == Green){ - for(int i=0; i < pixels; ++i){ - int c = tqGreen(data[i]); - c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; - data[i] = tqRgba(tqRed(data[i]), c, tqBlue(data[i]), tqAlpha(data[i])); - } - } - else{ - for(int i=0; i < pixels; ++i){ - int c = tqBlue(data[i]); - c = c + segTbl[c] > 255 ? 255 : c + segTbl[c]; - data[i] = tqRgba(tqRed(data[i]), tqGreen(data[i]), c, tqAlpha(data[i])); - } - } - - } - else{ - if(channel == Red){ - for(int i=0; i < pixels; ++i){ - int c = tqRed(data[i]); - c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; - data[i] = tqRgba(c, tqGreen(data[i]), tqBlue(data[i]), tqAlpha(data[i])); - } - } - else if(channel == Green){ - for(int i=0; i < pixels; ++i){ - int c = tqGreen(data[i]); - c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; - data[i] = tqRgba(tqRed(data[i]), c, tqBlue(data[i]), tqAlpha(data[i])); - } - } - else{ - for(int i=0; i < pixels; ++i){ - int c = tqBlue(data[i]); - c = c - segTbl[c] < 0 ? 0 : c - segTbl[c]; - data[i] = tqRgba(tqRed(data[i]), tqGreen(data[i]), c, tqAlpha(data[i])); - } - } - } - delete [] segTbl; - - return image; -} - -// Modulate an image with an RBG channel of another image -// -TQImage& KImageEffect::modulate(TQImage &image, TQImage &modImage, bool reverse, - ModulationType type, int factor, RGBComponent channel) -{ - if (image.width() == 0 || image.height() == 0 || - modImage.width() == 0 || modImage.height() == 0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::modulate : invalid image\n"; -#endif - return image; - } - - int r, g, b, h, s, v, a; - TQColor clr; - int mod=0; - unsigned int x1, x2, y1, y2; - register int x, y; - - // for image, we handle only depth 32 - if (image.depth()<32) image = image.convertDepth(32); - - // for modImage, we handle depth 8 and 32 - if (modImage.depth()<8) modImage = modImage.convertDepth(8); - - unsigned int *colorTable2 = (modImage.depth()==8) ? - modImage.tqcolorTable():0; - unsigned int *data1, *data2; - unsigned char *data2b; - unsigned int color1, color2; - - x1 = image.width(); y1 = image.height(); - x2 = modImage.width(); y2 = modImage.height(); - - for (y = 0; y < (int)y1; y++) { - data1 = (unsigned int *) image.scanLine(y); - data2 = (unsigned int *) modImage.scanLine( y%y2 ); - data2b = (unsigned char *) modImage.scanLine( y%y2 ); - - x=0; - while(x < (int)x1) { - color2 = (colorTable2) ? colorTable2[*data2b] : *data2; - if (reverse) { - color1 = color2; - color2 = *data1; - } - else - color1 = *data1; - - if (type == Intensity || type == Contrast) { - r = tqRed(color1); - g = tqGreen(color1); - b = tqBlue(color1); - if (channel != All) { - mod = (channel == Red) ? tqRed(color2) : - (channel == Green) ? tqGreen(color2) : - (channel == Blue) ? tqBlue(color2) : - (channel == Gray) ? tqGray(color2) : 0; - mod = mod*factor/50; - } - - if (type == Intensity) { - if (channel == All) { - r += r * factor/50 * tqRed(color2)/256; - g += g * factor/50 * tqGreen(color2)/256; - b += b * factor/50 * tqBlue(color2)/256; - } - else { - r += r * mod/256; - g += g * mod/256; - b += b * mod/256; - } - } - else { // Contrast - if (channel == All) { - r += (r-128) * factor/50 * tqRed(color2)/128; - g += (g-128) * factor/50 * tqGreen(color2)/128; - b += (b-128) * factor/50 * tqBlue(color2)/128; - } - else { - r += (r-128) * mod/128; - g += (g-128) * mod/128; - b += (b-128) * mod/128; - } - } - - if (r<0) r=0; if (r>255) r=255; - if (g<0) g=0; if (g>255) g=255; - if (b<0) b=0; if (b>255) b=255; - a = tqAlpha(*data1); - *data1 = tqRgba(r, g, b, a); - } - else if (type == Saturation || type == HueShift) { - clr.setRgb(color1); - clr.hsv(&h, &s, &v); - mod = (channel == Red) ? tqRed(color2) : - (channel == Green) ? tqGreen(color2) : - (channel == Blue) ? tqBlue(color2) : - (channel == Gray) ? tqGray(color2) : 0; - mod = mod*factor/50; - - if (type == Saturation) { - s -= s * mod/256; - if (s<0) s=0; if (s>255) s=255; - } - else { // HueShift - h += mod; - while(h<0) h+=360; - h %= 360; - } - - clr.setHsv(h, s, v); - a = tqAlpha(*data1); - *data1 = clr.rgb() | ((uint)(a & 0xff) << 24); - } - data1++; data2++; data2b++; x++; - if ( (x%x2) ==0) { data2 -= x2; data2b -= x2; } - } - } - return image; -} - - - -//====================================================================== -// -// Blend effects -// -//====================================================================== - - -// Nice and fast direct pixel manipulation -TQImage& KImageEffect::blend(const TQColor& clr, TQImage& dst, float opacity) -{ - if (dst.width() <= 0 || dst.height() <= 0) - return dst; - - if (opacity < 0.0 || opacity > 1.0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::blend : invalid opacity. Range [0, 1]\n"; -#endif - return dst; - } - - if (dst.depth() != 32) - dst = dst.convertDepth(32); - -#ifdef USE_QT4 - if (dst.format() != QImage::Format_ARGB32) - dst = dst.convertToFormat(QImage::Format_ARGB32); // This is needed because Qt4 has multiple variants with a 32 bit depth, and the routines below expect one specific variant (ARGB) -#endif - - int pixels = dst.width() * dst.height(); - -#ifdef USE_SSE2_INLINE_ASM - if ( KCPUInfo::haveExtension( KCPUInfo::IntelSSE2 ) && pixels > 16 ) { - TQ_UINT16 alpha = TQ_UINT16( ( 1.0 - opacity ) * 256.0 ); - - KIE8Pack packedalpha = { { alpha, alpha, alpha, 256, - alpha, alpha, alpha, 256 } }; - - TQ_UINT16 red = TQ_UINT16( clr.red() * 256 * opacity ); - TQ_UINT16 green = TQ_UINT16( clr.green() * 256 * opacity ); - TQ_UINT16 blue = TQ_UINT16( clr.blue() * 256 * opacity ); - - KIE8Pack packedcolor = { { blue, green, red, 0, - blue, green, red, 0 } }; - - // Prepare the XMM5, XMM6 and XMM7 registers for unpacking and blending - __asm__ __volatile__( - "pxor %%xmm7, %%xmm7\n\t" // Zero out XMM7 for unpacking - "movdqu (%0), %%xmm6\n\t" // Set up (1 - alpha) * 256 in XMM6 - "movdqu (%1), %%xmm5\n\t" // Set up color * alpha * 256 in XMM5 - : : "r"(&packedalpha), "r"(&packedcolor), - "m"(packedcolor), "m"(packedalpha) ); - - TQ_UINT32 *data = reinterpret_cast<TQ_UINT32*>( dst.bits() ); - - // Check how many pixels we need to process to achieve 16 byte tqalignment - int offset = (16 - (TQ_UINT32( data ) & 0x0f)) / 4; - - // The main loop processes 8 pixels / iteration - int remainder = (pixels - offset) % 8; - pixels -= remainder; - - // Alignment loop - for ( int i = 0; i < offset; i++ ) { - __asm__ __volatile__( - "movd (%0,%1,4), %%xmm0\n\t" // Load one pixel to XMM1 - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the pixel - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm0\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - "packuswb %%xmm1, %%xmm0\n\t" // Pack the pixel to a dword - "movd %%xmm0, (%0,%1,4)\n\t" // Write the pixel to the image - : : "r"(data), "r"(i) ); - } - - // Main loop - for ( int i = offset; i < pixels; i += 8 ) { - __asm__ __volatile( - // Load 8 pixels to XMM registers 1 - 4 - "movq (%0,%1,4), %%xmm0\n\t" // Load pixels 1 and 2 to XMM1 - "movq 8(%0,%1,4), %%xmm1\n\t" // Load pixels 3 and 4 to XMM2 - "movq 16(%0,%1,4), %%xmm2\n\t" // Load pixels 5 and 6 to XMM3 - "movq 24(%0,%1,4), %%xmm3\n\t" // Load pixels 7 and 8 to XMM4 - - // Prefetch the pixels for next iteration - "prefetchnta 32(%0,%1,4) \n\t" - - // Blend pixels 1 and 2 - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the pixels - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the pixels with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm0\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - - // Blend pixels 3 and 4 - "punpcklbw %%xmm7, %%xmm1\n\t" // Unpack the pixels - "pmullw %%xmm6, %%xmm1\n\t" // Multiply the pixels with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm1\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm1\n\t" // Divide by 256 - - // Blend pixels 5 and 6 - "punpcklbw %%xmm7, %%xmm2\n\t" // Unpack the pixels - "pmullw %%xmm6, %%xmm2\n\t" // Multiply the pixels with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm2\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm2\n\t" // Divide by 256 - - // Blend pixels 7 and 8 - "punpcklbw %%xmm7, %%xmm3\n\t" // Unpack the pixels - "pmullw %%xmm6, %%xmm3\n\t" // Multiply the pixels with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm3\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm3\n\t" // Divide by 256 - - // Pack the pixels into 2 double quadwords - "packuswb %%xmm1, %%xmm0\n\t" // Pack pixels 1 - 4 to a double qword - "packuswb %%xmm3, %%xmm2\n\t" // Pack pixles 5 - 8 to a double qword - - // Write the pixels back to the image - "movdqa %%xmm0, (%0,%1,4)\n\t" // Store pixels 1 - 4 - "movdqa %%xmm2, 16(%0,%1,4)\n\t" // Store pixels 5 - 8 - : : "r"(data), "r"(i) ); - } - - // Cleanup loop - for ( int i = pixels; i < pixels + remainder; i++ ) { - __asm__ __volatile__( - "movd (%0,%1,4), %%xmm0\n\t" // Load one pixel to XMM1 - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the pixel - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%xmm5, %%xmm0\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - "packuswb %%xmm1, %%xmm0\n\t" // Pack the pixel to a dword - "movd %%xmm0, (%0,%1,4)\n\t" // Write the pixel to the image - : : "r"(data), "r"(i) ); - } - } else -#endif - -#ifdef USE_MMX_INLINE_ASM - if ( KCPUInfo::haveExtension( KCPUInfo::IntelMMX ) && pixels > 1 ) { - TQ_UINT16 alpha = TQ_UINT16( ( 1.0 - opacity ) * 256.0 ); - KIE4Pack packedalpha = { { alpha, alpha, alpha, 256 } }; - - TQ_UINT16 red = TQ_UINT16( clr.red() * 256 * opacity ); - TQ_UINT16 green = TQ_UINT16( clr.green() * 256 * opacity ); - TQ_UINT16 blue = TQ_UINT16( clr.blue() * 256 * opacity ); - - KIE4Pack packedcolor = { { blue, green, red, 0 } }; - - __asm__ __volatile__( - "pxor %%mm7, %%mm7\n\t" // Zero out MM7 for unpacking - "movq (%0), %%mm6\n\t" // Set up (1 - alpha) * 256 in MM6 - "movq (%1), %%mm5\n\t" // Set up color * alpha * 256 in MM5 - : : "r"(&packedalpha), "r"(&packedcolor), "m"(packedcolor), "m"(packedalpha) ); - - TQ_UINT32 *data = reinterpret_cast<TQ_UINT32*>( dst.bits() ); - - // The main loop processes 4 pixels / iteration - int remainder = pixels % 4; - pixels -= remainder; - - // Main loop - for ( int i = 0; i < pixels; i += 4 ) { - __asm__ __volatile__( - // Load 4 pixels to MM registers 1 - 4 - "movd (%0,%1,4), %%mm0\n\t" // Load the 1st pixel to MM0 - "movd 4(%0,%1,4), %%mm1\n\t" // Load the 2nd pixel to MM1 - "movd 8(%0,%1,4), %%mm2\n\t" // Load the 3rd pixel to MM2 - "movd 12(%0,%1,4), %%mm3\n\t" // Load the 4th pixel to MM3 - - // Blend the first pixel - "punpcklbw %%mm7, %%mm0\n\t" // Unpack the pixel - "pmullw %%mm6, %%mm0\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%mm5, %%mm0\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%mm0\n\t" // Divide by 256 - - // Blend the second pixel - "punpcklbw %%mm7, %%mm1\n\t" // Unpack the pixel - "pmullw %%mm6, %%mm1\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%mm5, %%mm1\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%mm1\n\t" // Divide by 256 - - // Blend the third pixel - "punpcklbw %%mm7, %%mm2\n\t" // Unpack the pixel - "pmullw %%mm6, %%mm2\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%mm5, %%mm2\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%mm2\n\t" // Divide by 256 - - // Blend the fourth pixel - "punpcklbw %%mm7, %%mm3\n\t" // Unpack the pixel - "pmullw %%mm6, %%mm3\n\t" // Multiply the pixel with (1 - alpha) * 256 - "paddw %%mm5, %%mm3\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%mm3\n\t" // Divide by 256 - - // Pack the pixels into 2 quadwords - "packuswb %%mm1, %%mm0\n\t" // Pack pixels 1 and 2 to a qword - "packuswb %%mm3, %%mm2\n\t" // Pack pixels 3 and 4 to a qword - - // Write the pixels back to the image - "movq %%mm0, (%0,%1,4)\n\t" // Store pixels 1 and 2 - "movq %%mm2, 8(%0,%1,4)\n\t" // Store pixels 3 and 4 - : : "r"(data), "r"(i) ); - } - - // Cleanup loop - for ( int i = pixels; i < pixels + remainder; i++ ) { - __asm__ __volatile__( - "movd (%0,%1,4), %%mm0\n\t" // Load one pixel to MM1 - "punpcklbw %%mm7, %%mm0\n\t" // Unpack the pixel - "pmullw %%mm6, %%mm0\n\t" // Multiply the pixel with 1 - alpha * 256 - "paddw %%mm5, %%mm0\n\t" // Add color * alpha * 256 to the result - "psrlw $8, %%mm0\n\t" // Divide by 256 - "packuswb %%mm0, %%mm0\n\t" // Pack the pixel to a dword - "movd %%mm0, (%0,%1,4)\n\t" // Write the pixel to the image - : : "r"(data), "r"(i) ); - } - - // Empty the MMX state - __asm__ __volatile__("emms"); - } else -#endif // USE_MMX_INLINE_ASM - - { - int rcol, gcol, bcol; - clr.rgb(&rcol, &gcol, &bcol); - -#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) - register unsigned char *data = (unsigned char *)dst.bits() + 1; -#else // BGRA - register unsigned char *data = (unsigned char *)dst.bits(); -#endif - - for (register int i=0; i<pixels; i++) - { -#ifdef WORDS_BIGENDIAN - *data += (unsigned char)((rcol - *data) * opacity); - data++; - *data += (unsigned char)((gcol - *data) * opacity); - data++; - *data += (unsigned char)((bcol - *data) * opacity); - data++; -#else - *data += (unsigned char)((bcol - *data) * opacity); - data++; - *data += (unsigned char)((gcol - *data) * opacity); - data++; - *data += (unsigned char)((rcol - *data) * opacity); - data++; -#endif - data++; // skip alpha - } - } - - return dst; -} - -// Nice and fast direct pixel manipulation -TQImage& KImageEffect::blend(TQImage& src, TQImage& dst, float opacity) -{ - if (src.width() <= 0 || src.height() <= 0) - return dst; - if (dst.width() <= 0 || dst.height() <= 0) - return dst; - - if (src.width() != dst.width() || src.height() != dst.height()) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::blend : src and destination images are not the same size\n"; -#endif - return dst; - } - - if (opacity < 0.0 || opacity > 1.0) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::blend : invalid opacity. Range [0, 1]\n"; -#endif - return dst; - } - - if (src.depth() != 32) src = src.convertDepth(32); - if (dst.depth() != 32) dst = dst.convertDepth(32); - -#ifdef USE_QT4 - if (src.format() != QImage::Format_ARGB32) - src = dst.convertToFormat(QImage::Format_ARGB32); // This is needed because Qt4 has multiple variants with a 32 bit depth, and the routines below expect one specific variant (ARGB) - if (dst.format() != QImage::Format_ARGB32) - dst = dst.convertToFormat(QImage::Format_ARGB32); // This is needed because Qt4 has multiple variants with a 32 bit depth, and the routines below expect one specific variant (ARGB) -#endif - - int pixels = src.width() * src.height(); - -#ifdef USE_SSE2_INLINE_ASM - if ( KCPUInfo::haveExtension( KCPUInfo::IntelSSE2 ) && pixels > 16 ) { - TQ_UINT16 alpha = TQ_UINT16( opacity * 256.0 ); - KIE8Pack packedalpha = { { alpha, alpha, alpha, 0, - alpha, alpha, alpha, 0 } }; - - // Prepare the XMM6 and XMM7 registers for unpacking and blending - __asm__ __volatile__( - "pxor %%xmm7, %%xmm7\n\t" // Zero out XMM7 for unpacking - "movdqu (%0), %%xmm6\n\t" // Set up alpha * 256 in XMM6 - : : "r"(&packedalpha), "m"(packedalpha) ); - - TQ_UINT32 *data1 = reinterpret_cast<TQ_UINT32*>( src.bits() ); - TQ_UINT32 *data2 = reinterpret_cast<TQ_UINT32*>( dst.bits() ); - - // Check how many pixels we need to process to achieve 16 byte tqalignment - int offset = (16 - (TQ_UINT32( data2 ) & 0x0f)) / 4; - - // The main loop processes 4 pixels / iteration - int remainder = (pixels - offset) % 4; - pixels -= remainder; - - // Alignment loop - for ( int i = 0; i < offset; i++ ) { - __asm__ __volatile__( - "movd (%1,%2,4), %%xmm1\n\t" // Load one dst pixel to XMM1 - "punpcklbw %%xmm7, %%xmm1\n\t" // Unpack the pixel - "movd (%0,%2,4), %%xmm0\n\t" // Load one src pixel to XMM0 - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the pixel - "psubw %%xmm1, %%xmm0\n\t" // Subtract dst from src - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%xmm1\n\t" // Multiply dst with 256 - "paddw %%xmm1, %%xmm0\n\t" // Add dst to result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - "packuswb %%xmm1, %%xmm0\n\t" // Pack the pixel to a dword - "movd %%xmm0, (%1,%2,4)\n\t" // Write the pixel to the image - : : "r"(data1), "r"(data2), "r"(i) ); - } - - // Main loop - for ( int i = offset; i < pixels; i += 4 ) { - __asm__ __volatile__( - // Load 4 src pixels to XMM0 and XMM2 and 4 dst pixels to XMM1 and XMM3 - "movq (%0,%2,4), %%xmm0\n\t" // Load two src pixels to XMM0 - "movq (%1,%2,4), %%xmm1\n\t" // Load two dst pixels to XMM1 - "movq 8(%0,%2,4), %%xmm2\n\t" // Load two src pixels to XMM2 - "movq 8(%1,%2,4), %%xmm3\n\t" // Load two dst pixels to XMM3 - - // Prefetch the pixels for the iteration after the next one - "prefetchnta 32(%0,%2,4) \n\t" - "prefetchnta 32(%1,%2,4) \n\t" - - // Blend the first two pixels - "punpcklbw %%xmm7, %%xmm1\n\t" // Unpack the dst pixels - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the src pixels - "psubw %%xmm1, %%xmm0\n\t" // Subtract dst from src - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%xmm1\n\t" // Multiply dst with 256 - "paddw %%xmm1, %%xmm0\n\t" // Add dst to the result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - - // Blend the next two pixels - "punpcklbw %%xmm7, %%xmm3\n\t" // Unpack the dst pixels - "punpcklbw %%xmm7, %%xmm2\n\t" // Unpack the src pixels - "psubw %%xmm3, %%xmm2\n\t" // Subtract dst from src - "pmullw %%xmm6, %%xmm2\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%xmm3\n\t" // Multiply dst with 256 - "paddw %%xmm3, %%xmm2\n\t" // Add dst to the result - "psrlw $8, %%xmm2\n\t" // Divide by 256 - - // Write the pixels back to the image - "packuswb %%xmm2, %%xmm0\n\t" // Pack the pixels to a double qword - "movdqa %%xmm0, (%1,%2,4)\n\t" // Store the pixels - : : "r"(data1), "r"(data2), "r"(i) ); - } - - // Cleanup loop - for ( int i = pixels; i < pixels + remainder; i++ ) { - __asm__ __volatile__( - "movd (%1,%2,4), %%xmm1\n\t" // Load one dst pixel to XMM1 - "punpcklbw %%xmm7, %%xmm1\n\t" // Unpack the pixel - "movd (%0,%2,4), %%xmm0\n\t" // Load one src pixel to XMM0 - "punpcklbw %%xmm7, %%xmm0\n\t" // Unpack the pixel - "psubw %%xmm1, %%xmm0\n\t" // Subtract dst from src - "pmullw %%xmm6, %%xmm0\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%xmm1\n\t" // Multiply dst with 256 - "paddw %%xmm1, %%xmm0\n\t" // Add dst to result - "psrlw $8, %%xmm0\n\t" // Divide by 256 - "packuswb %%xmm1, %%xmm0\n\t" // Pack the pixel to a dword - "movd %%xmm0, (%1,%2,4)\n\t" // Write the pixel to the image - : : "r"(data1), "r"(data2), "r"(i) ); - } - } else -#endif // USE_SSE2_INLINE_ASM - -#ifdef USE_MMX_INLINE_ASM - if ( KCPUInfo::haveExtension( KCPUInfo::IntelMMX ) && pixels > 1 ) { - TQ_UINT16 alpha = TQ_UINT16( opacity * 256.0 ); - KIE4Pack packedalpha = { { alpha, alpha, alpha, 0 } }; - - // Prepare the MM6 and MM7 registers for blending and unpacking - __asm__ __volatile__( - "pxor %%mm7, %%mm7\n\t" // Zero out MM7 for unpacking - "movq (%0), %%mm6\n\t" // Set up alpha * 256 in MM6 - : : "r"(&packedalpha), "m"(packedalpha) ); - - TQ_UINT32 *data1 = reinterpret_cast<TQ_UINT32*>( src.bits() ); - TQ_UINT32 *data2 = reinterpret_cast<TQ_UINT32*>( dst.bits() ); - - // The main loop processes 2 pixels / iteration - int remainder = pixels % 2; - pixels -= remainder; - - // Main loop - for ( int i = 0; i < pixels; i += 2 ) { - __asm__ __volatile__( - // Load 2 src pixels to MM0 and MM2 and 2 dst pixels to MM1 and MM3 - "movd (%0,%2,4), %%mm0\n\t" // Load the 1st src pixel to MM0 - "movd (%1,%2,4), %%mm1\n\t" // Load the 1st dst pixel to MM1 - "movd 4(%0,%2,4), %%mm2\n\t" // Load the 2nd src pixel to MM2 - "movd 4(%1,%2,4), %%mm3\n\t" // Load the 2nd dst pixel to MM3 - - // Blend the first pixel - "punpcklbw %%mm7, %%mm0\n\t" // Unpack the src pixel - "punpcklbw %%mm7, %%mm1\n\t" // Unpack the dst pixel - "psubw %%mm1, %%mm0\n\t" // Subtract dst from src - "pmullw %%mm6, %%mm0\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%mm1\n\t" // Multiply dst with 256 - "paddw %%mm1, %%mm0\n\t" // Add dst to the result - "psrlw $8, %%mm0\n\t" // Divide by 256 - - // Blend the second pixel - "punpcklbw %%mm7, %%mm2\n\t" // Unpack the src pixel - "punpcklbw %%mm7, %%mm3\n\t" // Unpack the dst pixel - "psubw %%mm3, %%mm2\n\t" // Subtract dst from src - "pmullw %%mm6, %%mm2\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%mm3\n\t" // Multiply dst with 256 - "paddw %%mm3, %%mm2\n\t" // Add dst to the result - "psrlw $8, %%mm2\n\t" // Divide by 256 - - // Write the pixels back to the image - "packuswb %%mm2, %%mm0\n\t" // Pack the pixels to a qword - "movq %%mm0, (%1,%2,4)\n\t" // Store the pixels - : : "r"(data1), "r"(data2), "r"(i) ); - } - - // Blend the remaining pixel (if there is one) - if ( remainder ) { - __asm__ __volatile__( - "movd (%0), %%mm0\n\t" // Load one src pixel to MM0 - "punpcklbw %%mm7, %%mm0\n\t" // Unpack the src pixel - "movd (%1), %%mm1\n\t" // Load one dst pixel to MM1 - "punpcklbw %%mm7, %%mm1\n\t" // Unpack the dst pixel - "psubw %%mm1, %%mm0\n\t" // Subtract dst from src - "pmullw %%mm6, %%mm0\n\t" // Multiply the result with alpha * 256 - "psllw $8, %%mm1\n\t" // Multiply dst with 256 - "paddw %%mm1, %%mm0\n\t" // Add dst to result - "psrlw $8, %%mm0\n\t" // Divide by 256 - "packuswb %%mm0, %%mm0\n\t" // Pack the pixel to a dword - "movd %%mm0, (%1)\n\t" // Write the pixel to the image - : : "r"(data1 + pixels), "r"(data2 + pixels) ); - } - - // Empty the MMX state - __asm__ __volatile__("emms"); - } else -#endif // USE_MMX_INLINE_ASM - - { -#ifdef WORDS_BIGENDIAN // ARGB (skip alpha) - register unsigned char *data1 = (unsigned char *)dst.bits() + 1; - register unsigned char *data2 = (unsigned char *)src.bits() + 1; -#else // BGRA - register unsigned char *data1 = (unsigned char *)dst.bits(); - register unsigned char *data2 = (unsigned char *)src.bits(); -#endif - - for (register int i=0; i<pixels; i++) - { -#ifdef WORDS_BIGENDIAN - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; -#else - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; - *data1 += (unsigned char)((*(data2++) - *data1) * opacity); - data1++; -#endif - data1++; // skip alpha - data2++; - } - } - - return dst; -} - - -TQImage& KImageEffect::blend(TQImage &image, float initial_intensity, - const TQColor &bgnd, GradientType eff, - bool anti_dir) -{ - if (image.width() == 0 || image.height() == 0 || image.depth()!=32 ) { -#ifndef NDEBUG - std::cerr << "WARNING: KImageEffect::blend : invalid image\n"; -#endif - return image; - } - - int r_bgnd = bgnd.red(), g_bgnd = bgnd.green(), b_bgnd = bgnd.blue(); - int r, g, b; - int ind; - - unsigned int xi, xf, yi, yf; - unsigned int a; - - // check the boundaries of the initial intesity param - float unaffected = 1; - if (initial_intensity > 1) initial_intensity = 1; - if (initial_intensity < -1) initial_intensity = -1; - if (initial_intensity < 0) { - unaffected = 1. + initial_intensity; - initial_intensity = 0; - } - - - float intensity = initial_intensity; - float var = 1. - initial_intensity; - - if (anti_dir) { - initial_intensity = intensity = 1.; - var = -var; - } - - register int x, y; - - unsigned int *data = (unsigned int *)image.bits(); - - int image_width = image.width(); //Those can't change - int image_height = image.height(); - - - if( eff == VerticalGradient || eff == HorizontalGradient ) { - - // set the image domain to apply the effect to - xi = 0, xf = image_width; - yi = 0, yf = image_height; - if (eff == VerticalGradient) { - if (anti_dir) yf = (int)(image_height * unaffected); - else yi = (int)(image_height * (1 - unaffected)); - } - else { - if (anti_dir) xf = (int)(image_width * unaffected); - else xi = (int)(image_height * (1 - unaffected)); - } - - var /= (eff == VerticalGradient?yf-yi:xf-xi); - - int ind_base; - for (y = yi; y < (int)yf; y++) { - intensity = eff == VerticalGradient? intensity + var : - initial_intensity; - ind_base = image_width * y ; - for (x = xi; x < (int)xf ; x++) { - if (eff == HorizontalGradient) intensity += var; - ind = x + ind_base; - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - } - } - } - else if (eff == DiagonalGradient || eff == CrossDiagonalGradient) { - float xvar = var / 2 / image_width; // / unaffected; - float yvar = var / 2 / image_height; // / unaffected; - float tmp; - - for (x = 0; x < image_width ; x++) { - tmp = xvar * (eff == DiagonalGradient? x : image.width()-x-1); - ind = x; - for (y = 0; y < image_height ; y++) { - intensity = initial_intensity + tmp + yvar * y; - - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - - ind += image_width; - } - } - } - - else if (eff == RectangleGradient || eff == EllipticGradient) { - float xvar; - float yvar; - - for (x = 0; x < image_width / 2 + image_width % 2; x++) { - xvar = var / image_width * (image_width - x*2/unaffected-1); - for (y = 0; y < image_height / 2 + image_height % 2; y++) { - yvar = var / image_height * (image_height - y*2/unaffected -1); - - if (eff == RectangleGradient) - intensity = initial_intensity + QMAX(xvar, yvar); - else - intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); - if (intensity > 1) intensity = 1; - if (intensity < 0) intensity = 0; - - //NW - ind = x + image_width * y ; - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - - //NE - ind = image_width - x - 1 + image_width * y ; - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - } - } - - //CT loop is doubled because of stupid central row/column issue. - // other solution? - for (x = 0; x < image_width / 2; x++) { - xvar = var / image_width * (image_width - x*2/unaffected-1); - for (y = 0; y < image_height / 2; y++) { - yvar = var / image_height * (image_height - y*2/unaffected -1); - - if (eff == RectangleGradient) - intensity = initial_intensity + QMAX(xvar, yvar); - else - intensity = initial_intensity + sqrt(xvar * xvar + yvar * yvar); - if (intensity > 1) intensity = 1; - if (intensity < 0) intensity = 0; - - //SW - ind = x + image_width * (image_height - y -1) ; - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - - //SE - ind = image_width-x-1 + image_width * (image_height - y - 1) ; - r = tqRed (data[ind]) + (int)(intensity * - (r_bgnd - tqRed (data[ind]))); - g = tqGreen(data[ind]) + (int)(intensity * - (g_bgnd - tqGreen(data[ind]))); - b = tqBlue (data[ind]) + (int)(intensity * - (b_bgnd - tqBlue (data[ind]))); - if (r > 255) r = 255; if (r < 0 ) r = 0; - if (g > 255) g = 255; if (g < 0 ) g = 0; - if (b > 255) b = 255; if (b < 0 ) b = 0; - a = tqAlpha(data[ind]); - data[ind] = tqRgba(r, g, b, a); - } - } - } -#ifndef NDEBUG - else std::cerr << "KImageEffect::blend effect not implemented" << std::endl; -#endif - return image; -} - -// Not very efficient as we create a third big image... -// -TQImage& KImageEffect::blend(TQImage &image1, TQImage &image2, - GradientType gt, int xf, int yf) -{ - if (image1.width() == 0 || image1.height() == 0 || - image2.width() == 0 || image2.height() == 0) - return image1; - - TQImage image3; - - image3 = KImageEffect::unbalancedGradient(image1.size(), - TQColor(0,0,0), TQColor(255,255,255), - gt, xf, yf, 0); - - return blend(image1,image2,image3, Red); // Channel to use is arbitrary -} - -// Blend image2 into image1, using an RBG channel of blendImage -// -TQImage& KImageEffect::blend(TQImage &image1, TQImage &image2, - TQImage &blendImage, RGBComponent channel) -{ - if (image1.width() == 0 || image1.height() == 0 || - image2.width() == 0 || image2.height() == 0 || - blendImage.width() == 0 || blendImage.height() == 0) { -#ifndef NDEBUG - std::cerr << "KImageEffect::blend effect invalid image" << std::endl; -#endif - return image1; - } - - int r, g, b; - int ind1, ind2, ind3; - - unsigned int x1, x2, x3, y1, y2, y3; - unsigned int a; - - register int x, y; - - // for image1 and image2, we only handle depth 32 - if (image1.depth()<32) image1 = image1.convertDepth(32); - if (image2.depth()<32) image2 = image2.convertDepth(32); - - // for blendImage, we handle depth 8 and 32 - if (blendImage.depth()<8) blendImage = blendImage.convertDepth(8); - - unsigned int *colorTable3 = (blendImage.depth()==8) ? - blendImage.tqcolorTable():0; - - unsigned int *data1 = (unsigned int *)image1.bits(); - unsigned int *data2 = (unsigned int *)image2.bits(); - unsigned int *data3 = (unsigned int *)blendImage.bits(); - unsigned char *data3b = (unsigned char *)blendImage.bits(); - unsigned int color3; - - x1 = image1.width(); y1 = image1.height(); - x2 = image2.width(); y2 = image2.height(); - x3 = blendImage.width(); y3 = blendImage.height(); - - for (y = 0; y < (int)y1; y++) { - ind1 = x1*y; - ind2 = x2*(y%y2); - ind3 = x3*(y%y3); - - x=0; - while(x < (int)x1) { - color3 = (colorTable3) ? colorTable3[data3b[ind3]] : data3[ind3]; - - a = (channel == Red) ? tqRed(color3) : - (channel == Green) ? tqGreen(color3) : - (channel == Blue) ? tqBlue(color3) : tqGray(color3); - - r = (a*tqRed(data1[ind1]) + (256-a)*tqRed(data2[ind2]))/256; - g = (a*tqGreen(data1[ind1]) + (256-a)*tqGreen(data2[ind2]))/256; - b = (a*tqBlue(data1[ind1]) + (256-a)*tqBlue(data2[ind2]))/256; - - a = tqAlpha(data1[ind1]); - data1[ind1] = tqRgba(r, g, b, a); - - ind1++; ind2++; ind3++; x++; - if ( (x%x2) ==0) ind2 -= x2; - if ( (x%x3) ==0) ind3 -= x3; - } - } - return image1; -} - - -//====================================================================== -// -// Hash effects -// -//====================================================================== - -unsigned int KImageEffect::lHash(unsigned int c) -{ - unsigned char r = tqRed(c), g = tqGreen(c), b = tqBlue(c), a = tqAlpha(c); - unsigned char nr, ng, nb; - nr =(r >> 1) + (r >> 2); nr = nr > r ? 0 : nr; - ng =(g >> 1) + (g >> 2); ng = ng > g ? 0 : ng; - nb =(b >> 1) + (b >> 2); nb = nb > b ? 0 : nb; - - return tqRgba(nr, ng, nb, a); -} - - -// ----------------------------------------------------------------------------- - -unsigned int KImageEffect::uHash(unsigned int c) -{ - unsigned char r = tqRed(c), g = tqGreen(c), b = tqBlue(c), a = tqAlpha(c); - unsigned char nr, ng, nb; - nr = r + (r >> 3); nr = nr < r ? ~0 : nr; - ng = g + (g >> 3); ng = ng < g ? ~0 : ng; - nb = b + (b >> 3); nb = nb < b ? ~0 : nb; - - return tqRgba(nr, ng, nb, a); -} - - -// ----------------------------------------------------------------------------- - -TQImage& KImageEffect::hash(TQImage &image, Lighting lite, unsigned int spacing) -{ - if (image.width() == 0 || image.height() == 0) { -#ifndef NDEBUG - std::cerr << "KImageEffect::hash effect invalid image" << std::endl; -#endif - return image; - } - - register int x, y; - unsigned int *data = (unsigned int *)image.bits(); - unsigned int ind; - - //CT no need to do it if not enough space - if ((lite == NorthLite || - lite == SouthLite)&& - (unsigned)image.height() < 2+spacing) return image; - if ((lite == EastLite || - lite == WestLite)&& - (unsigned)image.height() < 2+spacing) return image; - - if (lite == NorthLite || lite == SouthLite) { - for (y = 0 ; y < image.height(); y = y + 2 + spacing) { - for (x = 0; x < image.width(); x++) { - ind = x + image.width() * y; - data[ind] = lite==NorthLite?uHash(data[ind]):lHash(data[ind]); - - ind = ind + image.width(); - data[ind] = lite==NorthLite?lHash(data[ind]):uHash(data[ind]); - } - } - } - - else if (lite == EastLite || lite == WestLite) { - for (y = 0 ; y < image.height(); y++) { - for (x = 0; x < image.width(); x = x + 2 + spacing) { - ind = x + image.width() * y; - data[ind] = lite==EastLite?uHash(data[ind]):lHash(data[ind]); - - ind++; - data[ind] = lite==EastLite?lHash(data[ind]):uHash(data[ind]); - } - } - } - - else if (lite == NWLite || lite == SELite) { - for (y = 0 ; y < image.height(); y++) { - for (x = 0; - x < (int)(image.width() - ((y & 1)? 1 : 0) * spacing); - x = x + 2 + spacing) { - ind = x + image.width() * y + ((y & 1)? 1 : 0); - data[ind] = lite==NWLite?uHash(data[ind]):lHash(data[ind]); - - ind++; - data[ind] = lite==NWLite?lHash(data[ind]):uHash(data[ind]); - } - } - } - - else if (lite == SWLite || lite == NELite) { - for (y = 0 ; y < image.height(); y++) { - for (x = 0 + ((y & 1)? 1 : 0); x < image.width(); x = x + 2 + spacing) { - ind = x + image.width() * y - ((y & 1)? 1 : 0); - data[ind] = lite==SWLite?uHash(data[ind]):lHash(data[ind]); - - ind++; - data[ind] = lite==SWLite?lHash(data[ind]):uHash(data[ind]); - } - } - } - - return image; -} - - -//====================================================================== -// -// Flatten effects -// -//====================================================================== - -TQImage& KImageEffect::flatten(TQImage &img, const TQColor &ca, - const TQColor &cb, int ncols) -{ - if (img.width() == 0 || img.height() == 0) - return img; - - // a bitmap is easy... - if (img.depth() == 1) { - img.setColor(0, ca.rgb()); - img.setColor(1, cb.rgb()); - return img; - } - - int r1 = ca.red(); int r2 = cb.red(); - int g1 = ca.green(); int g2 = cb.green(); - int b1 = ca.blue(); int b2 = cb.blue(); - int min = 0, max = 255; - - QRgb col; - - // Get minimum and maximum greylevel. - if (img.numColors()) { - // pseudocolor - for (int i = 0; i < img.numColors(); i++) { - col = img.color(i); - int mean = (tqRed(col) + tqGreen(col) + tqBlue(col)) / 3; - min = QMIN(min, mean); - max = QMAX(max, mean); - } - } else { - // truecolor - for (int y=0; y < img.height(); y++) - for (int x=0; x < img.width(); x++) { - col = img.pixel(x, y); - int mean = (tqRed(col) + tqGreen(col) + tqBlue(col)) / 3; - min = QMIN(min, mean); - max = QMAX(max, mean); - } - } - - // Conversion factors - float sr = ((float) r2 - r1) / (max - min); - float sg = ((float) g2 - g1) / (max - min); - float sb = ((float) b2 - b1) / (max - min); - - - // Repaint the image - if (img.numColors()) { - for (int i=0; i < img.numColors(); i++) { - col = img.color(i); - int mean = (tqRed(col) + tqGreen(col) + tqBlue(col)) / 3; - int r = (int) (sr * (mean - min) + r1 + 0.5); - int g = (int) (sg * (mean - min) + g1 + 0.5); - int b = (int) (sb * (mean - min) + b1 + 0.5); - img.setColor(i, tqRgba(r, g, b, tqAlpha(col))); - } - } else { - for (int y=0; y < img.height(); y++) - for (int x=0; x < img.width(); x++) { - col = img.pixel(x, y); - int mean = (tqRed(col) + tqGreen(col) + tqBlue(col)) / 3; - int r = (int) (sr * (mean - min) + r1 + 0.5); - int g = (int) (sg * (mean - min) + g1 + 0.5); - int b = (int) (sb * (mean - min) + b1 + 0.5); - img.setPixel(x, y, tqRgba(r, g, b, tqAlpha(col))); - } - } - - - // Dither if necessary - if ( (ncols <= 0) || ((img.numColors() != 0) && (img.numColors() <= ncols))) - return img; - - if (ncols == 1) ncols++; - if (ncols > 256) ncols = 256; - - TQColor *pal = new TQColor[ncols]; - sr = ((float) r2 - r1) / (ncols - 1); - sg = ((float) g2 - g1) / (ncols - 1); - sb = ((float) b2 - b1) / (ncols - 1); - - for (int i=0; i<ncols; i++) - pal[i] = TQColor(r1 + int(sr*i), g1 + int(sg*i), b1 + int(sb*i)); - - dither(img, pal, ncols); - - delete[] pal; - return img; -} - - -//====================================================================== -// -// Fade effects -// -//====================================================================== - -TQImage& KImageEffect::fade(TQImage &img, float val, const TQColor &color) -{ - if (img.width() == 0 || img.height() == 0) - return img; - - // We don't handle bitmaps - if (img.depth() == 1) - return img; - - unsigned char tbl[256]; - for (int i=0; i<256; i++) - tbl[i] = (int) (val * i + 0.5); - - int red = color.red(); - int green = color.green(); - int blue = color.blue(); - - QRgb col; - int r, g, b, cr, cg, cb; - - if (img.depth() <= 8) { - // pseudo color - for (int i=0; i<img.numColors(); i++) { - col = img.color(i); - cr = tqRed(col); cg = tqGreen(col); cb = tqBlue(col); - if (cr > red) - r = cr - tbl[cr - red]; - else - r = cr + tbl[red - cr]; - if (cg > green) - g = cg - tbl[cg - green]; - else - g = cg + tbl[green - cg]; - if (cb > blue) - b = cb - tbl[cb - blue]; - else - b = cb + tbl[blue - cb]; - img.setColor(i, tqRgba(r, g, b, tqAlpha(col))); - } - - } else { - // truecolor - for (int y=0; y<img.height(); y++) { - QRgb *data = (QRgb *) img.scanLine(y); - for (int x=0; x<img.width(); x++) { - col = *data; - cr = tqRed(col); cg = tqGreen(col); cb = tqBlue(col); - if (cr > red) - r = cr - tbl[cr - red]; - else - r = cr + tbl[red - cr]; - if (cg > green) - g = cg - tbl[cg - green]; - else - g = cg + tbl[green - cg]; - if (cb > blue) - b = cb - tbl[cb - blue]; - else - b = cb + tbl[blue - cb]; - *data++ = tqRgba(r, g, b, tqAlpha(col)); - } - } - } - - return img; -} - -//====================================================================== -// -// Color effects -// -//====================================================================== - -// This code is adapted from code (C) Rik Hemsley <rik@kde.org> -// -// The formula used (r + b + g) /3 is different from the tqGray formula -// used by Qt. This is because our formula is much much faster. If, -// however, it turns out that this is producing sub-optimal images, -// then it will have to change (kurt) -// -// It does produce lower quality grayscale ;-) Use fast == true for the fast -// algorithm, false for the higher quality one (mosfet). -TQImage& KImageEffect::toGray(TQImage &img, bool fast) -{ - if (img.width() == 0 || img.height() == 0) - return img; - - if(fast){ - if (img.depth() == 32) { - register uchar * r(img.bits()); - register uchar * g(img.bits() + 1); - register uchar * b(img.bits() + 2); - - uchar * end(img.bits() + img.numBytes()); - - while (r != end) { - - *r = *g = *b = (((*r + *g) >> 1) + *b) >> 1; // (r + b + g) / 3 - - r += 4; - g += 4; - b += 4; - } - } - else - { - for (int i = 0; i < img.numColors(); i++) - { - register uint r = tqRed(img.color(i)); - register uint g = tqGreen(img.color(i)); - register uint b = tqBlue(img.color(i)); - - register uint gray = (((r + g) >> 1) + b) >> 1; - img.setColor(i, tqRgba(gray, gray, gray, tqAlpha(img.color(i)))); - } - } - } - else{ - int pixels = img.depth() > 8 ? img.width()*img.height() : - img.numColors(); - unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : - (unsigned int *)img.tqcolorTable(); - int val, i; - for(i=0; i < pixels; ++i){ - val = tqGray(data[i]); - data[i] = tqRgba(val, val, val, tqAlpha(data[i])); - } - } - return img; -} - -// CT 29Jan2000 - desaturation algorithms -TQImage& KImageEffect::desaturate(TQImage &img, float desat) -{ - if (img.width() == 0 || img.height() == 0) - return img; - - if (desat < 0) desat = 0.; - if (desat > 1) desat = 1.; - int pixels = img.depth() > 8 ? img.width()*img.height() : - img.numColors(); - unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : - (unsigned int *)img.tqcolorTable(); - int h, s, v, i; - TQColor clr; // keep constructor out of loop (mosfet) - for(i=0; i < pixels; ++i){ - clr.setRgb(data[i]); - clr.hsv(&h, &s, &v); - clr.setHsv(h, (int)(s * (1. - desat)), v); - data[i] = clr.rgb(); - } - return img; -} - -// Contrast stuff (mosfet) -TQImage& KImageEffect::contrast(TQImage &img, int c) -{ - if (img.width() == 0 || img.height() == 0) - return img; - - if(c > 255) - c = 255; - if(c < -255) - c = -255; - int pixels = img.depth() > 8 ? img.width()*img.height() : - img.numColors(); - unsigned int *data = img.depth() > 8 ? (unsigned int *)img.bits() : - (unsigned int *)img.tqcolorTable(); - int i, r, g, b; - for(i=0; i < pixels; ++i){ - r = tqRed(data[i]); - g = tqGreen(data[i]); - b = tqBlue(data[i]); - if(tqGray(data[i]) <= 127){ - if(r - c > 0) - r -= c; - else - r = 0; - if(g - c > 0) - g -= c; - else - g = 0; - if(b - c > 0) - b -= c; - else - b = 0; - } - else{ - if(r + c <= 255) - r += c; - else - r = 255; - if(g + c <= 255) - g += c; - else - g = 255; - if(b + c <= 255) - b += c; - else - b = 255; - } - data[i] = tqRgba(r, g, b, tqAlpha(data[i])); - } - return(img); -} - -//====================================================================== -// -// Dithering effects -// -//====================================================================== - -// adapted from kFSDither (C) 1997 Martin Jones (mjones@kde.org) -// -// Floyd-Steinberg dithering -// Ref: Bitmapped Graphics Programming in C++ -// Marv Luse, Addison-Wesley Publishing, 1993. -TQImage& KImageEffect::dither(TQImage &img, const TQColor *palette, int size) -{ - if (img.width() == 0 || img.height() == 0 || - palette == 0 || img.depth() <= 8) - return img; - - TQImage dImage( img.width(), img.height(), 8, size ); - int i; - - dImage.setNumColors( size ); - for ( i = 0; i < size; i++ ) - dImage.setColor( i, palette[ i ].rgb() ); - - int *rerr1 = new int [ img.width() * 2 ]; - int *gerr1 = new int [ img.width() * 2 ]; - int *berr1 = new int [ img.width() * 2 ]; - - memset( rerr1, 0, sizeof( int ) * img.width() * 2 ); - memset( gerr1, 0, sizeof( int ) * img.width() * 2 ); - memset( berr1, 0, sizeof( int ) * img.width() * 2 ); - - int *rerr2 = rerr1 + img.width(); - int *gerr2 = gerr1 + img.width(); - int *berr2 = berr1 + img.width(); - - for ( int j = 0; j < img.height(); j++ ) - { - uint *ip = (uint * )img.scanLine( j ); - uchar *dp = dImage.scanLine( j ); - - for ( i = 0; i < img.width(); i++ ) - { - rerr1[i] = rerr2[i] + tqRed( *ip ); - rerr2[i] = 0; - gerr1[i] = gerr2[i] + tqGreen( *ip ); - gerr2[i] = 0; - berr1[i] = berr2[i] + tqBlue( *ip ); - berr2[i] = 0; - ip++; - } - - *dp++ = nearestColor( rerr1[0], gerr1[0], berr1[0], palette, size ); - - for ( i = 1; i < img.width()-1; i++ ) - { - int indx = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); - *dp = indx; - - int rerr = rerr1[i]; - rerr -= palette[indx].red(); - int gerr = gerr1[i]; - gerr -= palette[indx].green(); - int berr = berr1[i]; - berr -= palette[indx].blue(); - - // diffuse red error - rerr1[ i+1 ] += ( rerr * 7 ) >> 4; - rerr2[ i-1 ] += ( rerr * 3 ) >> 4; - rerr2[ i ] += ( rerr * 5 ) >> 4; - rerr2[ i+1 ] += ( rerr ) >> 4; - - // diffuse green error - gerr1[ i+1 ] += ( gerr * 7 ) >> 4; - gerr2[ i-1 ] += ( gerr * 3 ) >> 4; - gerr2[ i ] += ( gerr * 5 ) >> 4; - gerr2[ i+1 ] += ( gerr ) >> 4; - - // diffuse red error - berr1[ i+1 ] += ( berr * 7 ) >> 4; - berr2[ i-1 ] += ( berr * 3 ) >> 4; - berr2[ i ] += ( berr * 5 ) >> 4; - berr2[ i+1 ] += ( berr ) >> 4; - - dp++; - } - - *dp = nearestColor( rerr1[i], gerr1[i], berr1[i], palette, size ); - } - - delete [] rerr1; - delete [] gerr1; - delete [] berr1; - - img = dImage; - return img; -} - -int KImageEffect::nearestColor( int r, int g, int b, const TQColor *palette, int size ) -{ - if (palette == 0) - return 0; - - int dr = palette[0].red() - r; - int dg = palette[0].green() - g; - int db = palette[0].blue() - b; - - int minDist = dr*dr + dg*dg + db*db; - int nearest = 0; - - for (int i = 1; i < size; i++ ) - { - dr = palette[i].red() - r; - dg = palette[i].green() - g; - db = palette[i].blue() - b; - - int dist = dr*dr + dg*dg + db*db; - - if ( dist < minDist ) - { - minDist = dist; - nearest = i; - } - } - - return nearest; -} - -bool KImageEffect::blend( - const TQImage & upper, - const TQImage & lower, - TQImage & output -) -{ - if ( - upper.width() > lower.width() || - upper.height() > lower.height() || - upper.depth() != 32 || - lower.depth() != 32 - ) - { -#ifndef NDEBUG - std::cerr << "KImageEffect::blend : Sizes not correct\n" ; -#endif - return false; - } - - output = lower.copy(); - - register uchar *i, *o; - register int a; - register int col; - register int w = upper.width(); - int row(upper.height() - 1); - - do { - - i = const_cast<TQImage&>(upper).scanLine(row); - o = const_cast<TQImage&>(output).scanLine(row); - - col = w << 2; - --col; - - do { - - while (!(a = i[col]) && (col != 3)) { - --col; --col; --col; --col; - } - - --col; - o[col] += ((i[col] - o[col]) * a) >> 8; - - --col; - o[col] += ((i[col] - o[col]) * a) >> 8; - - --col; - o[col] += ((i[col] - o[col]) * a) >> 8; - - } while (col--); - - } while (row--); - - return true; -} - -#if 0 -// Not yet... -bool KImageEffect::blend( - const TQImage & upper, - const TQImage & lower, - TQImage & output, - const TQRect & destRect -) -{ - output = lower.copy(); - return output; -} - -#endif - -bool KImageEffect::blend( - int &x, int &y, - const TQImage & upper, - const TQImage & lower, - TQImage & output -) -{ - int cx=0, cy=0, cw=upper.width(), ch=upper.height(); - - if ( upper.width() + x > lower.width() || - upper.height() + y > lower.height() || - x < 0 || y < 0 || - upper.depth() != 32 || lower.depth() != 32 ) - { - if ( x > lower.width() || y > lower.height() ) return false; - if ( upper.width()<=0 || upper.height() <= 0 ) return false; - if ( lower.width()<=0 || lower.height() <= 0 ) return false; - - if (x<0) {cx=-x; cw+=x; x=0; }; - if (cw + x > lower.width()) { cw=lower.width()-x; }; - if (y<0) {cy=-y; ch+=y; y=0; }; - if (ch + y > lower.height()) { ch=lower.height()-y; }; - - if ( cx >= upper.width() || cy >= upper.height() ) return true; - if ( cw <= 0 || ch <= 0 ) return true; - } - - output.create(cw,ch,32); -// output.setAlphaBuffer(true); // I should do some benchmarks to see if - // this is worth the effort - - register QRgb *i, *o, *b; - - register int a; - register int j,k; - for (j=0; j<ch; j++) - { - b=reinterpret_cast<QRgb *>(&const_cast<TQImage&>(lower).scanLine(y+j) [ (x+cw) << 2 ]); - i=reinterpret_cast<QRgb *>(&const_cast<TQImage&>(upper).scanLine(cy+j)[ (cx+cw) << 2 ]); - o=reinterpret_cast<QRgb *>(&const_cast<TQImage&>(output).scanLine(j) [ cw << 2 ]); - - k=cw-1; - --b; --i; --o; - do - { - while ( !(a=tqAlpha(*i)) && k>0 ) - { - i--; -// *o=0; - *o=*b; - --o; --b; - k--; - }; -// *o=0xFF; - *o = tqRgb(tqRed(*b) + (((tqRed(*i) - tqRed(*b)) * a) >> 8), - tqGreen(*b) + (((tqGreen(*i) - tqGreen(*b)) * a) >> 8), - tqBlue(*b) + (((tqBlue(*i) - tqBlue(*b)) * a) >> 8)); - --i; --o; --b; - } while (k--); - } - - return true; -} - -bool KImageEffect::blendOnLower( - int x, int y, - const TQImage & upper, - const TQImage & lower -) -{ - int cx=0, cy=0, cw=upper.width(), ch=upper.height(); - - if ( upper.depth() != 32 || lower.depth() != 32 ) return false; - if ( x + cw > lower.width() || - y + ch > lower.height() || - x < 0 || y < 0 ) - { - if ( x > lower.width() || y > lower.height() ) return true; - if ( upper.width()<=0 || upper.height() <= 0 ) return true; - if ( lower.width()<=0 || lower.height() <= 0 ) return true; - - if (x<0) {cx=-x; cw+=x; x=0; }; - if (cw + x > lower.width()) { cw=lower.width()-x; }; - if (y<0) {cy=-y; ch+=y; y=0; }; - if (ch + y > lower.height()) { ch=lower.height()-y; }; - - if ( cx >= upper.width() || cy >= upper.height() ) return true; - if ( cw <= 0 || ch <= 0 ) return true; - } - - register uchar *i, *b; - register int a; - register int k; - - for (int j=0; j<ch; j++) - { - b=&const_cast<TQImage&>(lower).scanLine(y+j) [ (x+cw) << 2 ]; - i=&const_cast<TQImage&>(upper).scanLine(cy+j)[ (cx+cw) << 2 ]; - - k=cw-1; - --b; --i; - do - { -#ifndef WORDS_BIGENDIAN - while ( !(a=*i) && k>0 ) -#else - while ( !(a=*(i-3)) && k>0 ) -#endif - { - i-=4; b-=4; k--; - }; - -#ifndef WORDS_BIGENDIAN - --i; --b; - *b += ( ((*i - *b) * a) >> 8 ); - --i; --b; - *b += ( ((*i - *b) * a) >> 8 ); - --i; --b; - *b += ( ((*i - *b) * a) >> 8 ); - --i; --b; -#else - *b += ( ((*i - *b) * a) >> 8 ); - --i; --b; - *b += ( ((*i - *b) * a) >> 8 ); - --i; --b; - *b += ( ((*i - *b) * a) >> 8 ); - i -= 2; b -= 2; -#endif - } while (k--); - } - - return true; -} - -void KImageEffect::blendOnLower(const TQImage &upper, const TQPoint &upperOffset, - TQImage &lower, const TQRect &lowerRect) -{ - // clip rect - TQRect lr = lowerRect & lower.rect(); - lr.setWidth( QMIN(lr.width(), upper.width()-upperOffset.x()) ); - lr.setHeight( QMIN(lr.height(), upper.height()-upperOffset.y()) ); - if ( !lr.isValid() ) return; - - // blend - for (int y = 0; y < lr.height(); y++) { - for (int x = 0; x < lr.width(); x++) { - QRgb *b = reinterpret_cast<QRgb*>(const_cast<TQImage&>(lower).scanLine(lr.y() + y)+ (lr.x() + x) * sizeof(QRgb)); - QRgb *d = reinterpret_cast<QRgb*>(const_cast<TQImage&>(upper).scanLine(upperOffset.y() + y) + (upperOffset.x() + x) * sizeof(QRgb)); - int a = tqAlpha(*d); - *b = tqRgb(tqRed(*b) - (((tqRed(*b) - tqRed(*d)) * a) >> 8), - tqGreen(*b) - (((tqGreen(*b) - tqGreen(*d)) * a) >> 8), - tqBlue(*b) - (((tqBlue(*b) - tqBlue(*d)) * a) >> 8)); - } - } -} - -void KImageEffect::blendOnLower(const TQImage &upper, const TQPoint &upperOffset, - TQImage &lower, const TQRect &lowerRect, float opacity) -{ - // clip rect - TQRect lr = lowerRect & lower.rect(); - lr.setWidth( QMIN(lr.width(), upper.width()-upperOffset.x()) ); - lr.setHeight( QMIN(lr.height(), upper.height()-upperOffset.y()) ); - if ( !lr.isValid() ) return; - - // blend - for (int y = 0; y < lr.height(); y++) { - for (int x = 0; x < lr.width(); x++) { - QRgb *b = reinterpret_cast<QRgb*>(const_cast<TQImage&>(lower).scanLine(lr.y() + y)+ (lr.x() + x) * sizeof(QRgb)); - QRgb *d = reinterpret_cast<QRgb*>(const_cast<TQImage&>(upper).scanLine(upperOffset.y() + y) + (upperOffset.x() + x) * sizeof(QRgb)); - int a = tqRound(opacity * tqAlpha(*d)); - *b = tqRgb(tqRed(*b) - (((tqRed(*b) - tqRed(*d)) * a) >> 8), - tqGreen(*b) - (((tqGreen(*b) - tqGreen(*d)) * a) >> 8), - tqBlue(*b) - (((tqBlue(*b) - tqBlue(*d)) * a) >> 8)); - } - } -} - -TQRect KImageEffect::computeDestinationRect(const TQSize &lowerSize, - Disposition disposition, TQImage &upper) -{ - int w = lowerSize.width(); - int h = lowerSize.height(); - int ww = upper.width(); - int wh = upper.height(); - TQRect d; - - switch (disposition) { - case NoImage: - break; - case Centered: - d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh); - break; - case Tiled: - d.setRect(0, 0, w, h); - break; - case CenterTiled: - d.setCoords(-ww + ((w - ww) / 2) % ww, -wh + ((h - wh) / 2) % wh, - w-1, h-1); - break; - case Scaled: - upper = upper.smoothScale(w, h); - d.setRect(0, 0, w, h); - break; - case CenteredAutoFit: - if( ww <= w && wh <= h ) { - d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh); // like Centered - break; - } - // fall through - case CenteredMaxpect: { - double sx = (double) w / ww; - double sy = (double) h / wh; - if (sx > sy) { - ww = (int)(sy * ww); - wh = h; - } else { - wh = (int)(sx * wh); - ww = w; - } - upper = upper.smoothScale(ww, wh); - d.setRect((w - ww) / 2, (h - wh) / 2, ww, wh); - break; - } - case TiledMaxpect: { - double sx = (double) w / ww; - double sy = (double) h / wh; - if (sx > sy) { - ww = (int)(sy * ww); - wh = h; - } else { - wh = (int)(sx * wh); - ww = w; - } - upper = upper.smoothScale(ww, wh); - d.setRect(0, 0, w, h); - break; - } - } - - return d; -} - -void KImageEffect::blendOnLower(TQImage &upper, TQImage &lower, - Disposition disposition, float opacity) -{ - TQRect r = computeDestinationRect(lower.size(), disposition, upper); - for (int y = r.top(); y<r.bottom(); y += upper.height()) - for (int x = r.left(); x<r.right(); x += upper.width()) - blendOnLower(upper, TQPoint(-QMIN(x, 0), -QMIN(y, 0)), - lower, TQRect(x, y, upper.width(), upper.height()), opacity); -} - - -// For selected icons -TQImage& KImageEffect::selectedImage( TQImage &img, const TQColor &col ) -{ - return blend( col, img, 0.5); -} - -// -// =================================================================== -// Effects originally ported from ImageMagick for PixiePlus, plus a few -// new ones. (mosfet 05/26/2003) -// =================================================================== -// -/* - Portions of this software are based on ImageMagick. Such portions are clearly -marked as being ported from ImageMagick. ImageMagick is copyrighted under the -following conditions: - -Copyright (C) 2003 ImageMagick Studio, a non-profit organization dedicated to -making software imaging solutions freely available. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files ("ImageMagick"), to deal -in ImageMagick without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of ImageMagick, and to permit persons to whom the ImageMagick is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of ImageMagick. - -The software is provided "as is", without warranty of any kind, express or -implied, including but not limited to the warranties of merchantability, -fitness for a particular purpose and noninfringement. In no event shall -ImageMagick Studio be liable for any claim, damages or other liability, -whether in an action of contract, tort or otherwise, arising from, out of or -in connection with ImageMagick or the use or other dealings in ImageMagick. - -Except as contained in this notice, the name of the ImageMagick Studio shall -not be used in advertising or otherwise to promote the sale, use or other -dealings in ImageMagick without prior written authorization from the -ImageMagick Studio. -*/ - -TQImage KImageEffect::sample(TQImage &src, int w, int h) -{ - if(w == src.width() && h == src.height()) - return(src); - - int depth = src.depth(); - TQImage dest(w, h, depth, depth <= 8 ? src.numColors() : 0, - depth == 1 ? TQImage::LittleEndian : TQImage::IgnoreEndian); - int *x_offset = (int *)malloc(w*sizeof(int)); - int *y_offset = (int *)malloc(h*sizeof(int)); - if(!x_offset || !y_offset){ -#ifndef NDEBUG - qWarning("KImageEffect::sample(): Unable to allocate pixel buffer"); -#endif - free(x_offset); - free(y_offset); - return(src); - } - - // init pixel offsets - for(int x=0; x < w; ++x) - x_offset[x] = (int)(x*src.width()/((double)w)); - for(int y=0; y < h; ++y) - y_offset[y] = (int)(y*src.height()/((double)h)); - - if(depth > 8){ // DirectClass source image - for(int y=0; y < h; ++y){ - unsigned int *destData = (unsigned int *)dest.scanLine(y); - unsigned int *srcData = (unsigned int *)src.scanLine(y_offset[y]); - for(int x=0; x < w; ++x) - destData[x] = srcData[x_offset[x]]; - } - } - else if(depth == 1) { - int r = src.bitOrder() == TQImage::LittleEndian; - memcpy(dest.tqcolorTable(), src.tqcolorTable(), src.numColors()*sizeof(QRgb)); - for(int y=0; y < h; ++y){ - unsigned char *destData = dest.scanLine(y); - unsigned char *srcData = src.scanLine(y_offset[y]); - for(int x=0; x < w; ++x){ - int k = x_offset[x]; - int l = r ? (k & 7) : (7 - (k&7)); - if(srcData[k >> 3] & (1 << l)) - destData[x >> 3] |= 1 << (x & 7); - else - destData[x >> 3] &= ~(1 << (x & 7)); - } - } - } - else{ // PseudoClass source image - memcpy(dest.tqcolorTable(), src.tqcolorTable(), src.numColors()*sizeof(QRgb)); - for(int y=0; y < h; ++y){ - unsigned char *destData = dest.scanLine(y); - unsigned char *srcData = src.scanLine(y_offset[y]); - for(int x=0; x < w; ++x) - destData[x] = srcData[x_offset[x]]; - } - } - free(x_offset); - free(y_offset); - return(dest); -} - -void KImageEffect::threshold(TQImage &img, unsigned int threshold) -{ - int i, count; - unsigned int *data; - if(img.depth() > 8){ // DirectClass - count = img.width()*img.height(); - data = (unsigned int *)img.bits(); - } - else{ // PsudeoClass - count = img.numColors(); - data = (unsigned int *)img.tqcolorTable(); - } - for(i=0; i < count; ++i) - data[i] = intensityValue(data[i]) < threshold ? QColor(Qt::black).rgb() : QColor(Qt::white).rgb(); -} - -void KImageEffect::hull(const int x_offset, const int y_offset, - const int polarity, const int columns, - const int rows, - unsigned int *f, unsigned int *g) -{ - int x, y; - - unsigned int *p, *q, *r, *s; - unsigned int v; - if(f == NULL || g == NULL) - return; - p=f+(columns+2); - q=g+(columns+2); - r=p+(y_offset*(columns+2)+x_offset); - for (y=0; y < rows; y++){ - p++; - q++; - r++; - if(polarity > 0) - for (x=0; x < columns; x++){ - v=(*p); - if (*r > v) - v++; - *q=v; - p++; - q++; - r++; - } - else - for(x=0; x < columns; x++){ - v=(*p); - if (v > (unsigned int) (*r+1)) - v--; - *q=v; - p++; - q++; - r++; - } - p++; - q++; - r++; - } - p=f+(columns+2); - q=g+(columns+2); - r=q+(y_offset*(columns+2)+x_offset); - s=q-(y_offset*(columns+2)+x_offset); - for(y=0; y < rows; y++){ - p++; - q++; - r++; - s++; - if(polarity > 0) - for(x=0; x < (int) columns; x++){ - v=(*q); - if (((unsigned int) (*s+1) > v) && (*r > v)) - v++; - *p=v; - p++; - q++; - r++; - s++; - } - else - for (x=0; x < columns; x++){ - v=(*q); - if (((unsigned int) (*s+1) < v) && (*r < v)) - v--; - *p=v; - p++; - q++; - r++; - s++; - } - p++; - q++; - r++; - s++; - } -} - -TQImage KImageEffect::despeckle(TQImage &src) -{ - int i, j, x, y; - unsigned int *blue_channel, *red_channel, *green_channel, *buffer, - *alpha_channel; - int packets; - static const int - X[4]= {0, 1, 1,-1}, - Y[4]= {1, 0, 1, 1}; - - unsigned int *destData; - TQImage dest(src.width(), src.height(), 32); - - packets = (src.width()+2)*(src.height()+2); - red_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); - green_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); - blue_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); - alpha_channel = (unsigned int *)calloc(packets, sizeof(unsigned int)); - buffer = (unsigned int *)calloc(packets, sizeof(unsigned int)); - if(!red_channel || ! green_channel || ! blue_channel || ! alpha_channel || - !buffer){ - free(red_channel); - free(green_channel); - free(blue_channel); - free(alpha_channel); - free(buffer); - return(src); - } - - // copy image pixels to color component buffers - j = src.width()+2; - if(src.depth() > 8){ // DirectClass source image - unsigned int *srcData; - for(y=0; y < src.height(); ++y){ - srcData = (unsigned int *)src.scanLine(y); - ++j; - for(x=0; x < src.width(); ++x){ - red_channel[j] = tqRed(srcData[x]); - green_channel[j] = tqGreen(srcData[x]); - blue_channel[j] = tqBlue(srcData[x]); - alpha_channel[j] = tqAlpha(srcData[x]); - ++j; - } - ++j; - } - } - else{ // PsudeoClass source image - unsigned char *srcData; - unsigned int *cTable = src.tqcolorTable(); - unsigned int pixel; - for(y=0; y < src.height(); ++y){ - srcData = (unsigned char *)src.scanLine(y); - ++j; - for(x=0; x < src.width(); ++x){ - pixel = *(cTable+srcData[x]); - red_channel[j] = tqRed(pixel); - green_channel[j] = tqGreen(pixel); - blue_channel[j] = tqBlue(pixel); - alpha_channel[j] = tqAlpha(pixel); - ++j; - } - ++j; - } - } - // reduce speckle in red channel - for(i=0; i < 4; i++){ - hull(X[i],Y[i],1,src.width(),src.height(),red_channel,buffer); - hull(-X[i],-Y[i],1,src.width(),src.height(),red_channel,buffer); - hull(-X[i],-Y[i],-1,src.width(),src.height(),red_channel,buffer); - hull(X[i],Y[i],-1,src.width(),src.height(),red_channel,buffer); - } - // reduce speckle in green channel - for (i=0; i < packets; i++) - buffer[i]=0; - for (i=0; i < 4; i++){ - hull(X[i],Y[i],1,src.width(),src.height(),green_channel,buffer); - hull(-X[i],-Y[i],1,src.width(),src.height(),green_channel,buffer); - hull(-X[i],-Y[i],-1,src.width(),src.height(),green_channel,buffer); - hull(X[i],Y[i],-1,src.width(),src.height(),green_channel,buffer); - } - // reduce speckle in blue channel - for (i=0; i < packets; i++) - buffer[i]=0; - for (i=0; i < 4; i++){ - hull(X[i],Y[i],1,src.width(),src.height(),blue_channel,buffer); - hull(-X[i],-Y[i],1,src.width(),src.height(),blue_channel,buffer); - hull(-X[i],-Y[i],-1,src.width(),src.height(),blue_channel,buffer); - hull(X[i],Y[i],-1,src.width(),src.height(),blue_channel,buffer); - } - // copy color component buffers to despeckled image - j = dest.width()+2; - for(y=0; y < dest.height(); ++y) - { - destData = (unsigned int *)dest.scanLine(y); - ++j; - for (x=0; x < dest.width(); ++x) - { - destData[x] = tqRgba(red_channel[j], green_channel[j], - blue_channel[j], alpha_channel[j]); - ++j; - } - ++j; - } - free(buffer); - free(red_channel); - free(green_channel); - free(blue_channel); - free(alpha_channel); - return(dest); -} - -unsigned int KImageEffect::generateNoise(unsigned int pixel, - NoiseType noise_type) -{ -#define NoiseEpsilon 1.0e-5 -#define NoiseMask 0x7fff -#define SigmaUniform 4.0 -#define SigmaGaussian 4.0 -#define SigmaImpulse 0.10 -#define SigmaLaplacian 10.0 -#define SigmaMultiplicativeGaussian 0.5 -#define SigmaPoisson 0.05 -#define TauGaussian 20.0 - - double alpha, beta, sigma, value; - alpha=(double) (rand() & NoiseMask)/NoiseMask; - if (alpha == 0.0) - alpha=1.0; - switch(noise_type){ - case UniformNoise: - default: - { - value=(double) pixel+SigmaUniform*(alpha-0.5); - break; - } - case GaussianNoise: - { - double tau; - - beta=(double) (rand() & NoiseMask)/NoiseMask; - sigma=sqrt(-2.0*log(alpha))*cos(2.0*M_PI*beta); - tau=sqrt(-2.0*log(alpha))*sin(2.0*M_PI*beta); - value=(double) pixel+ - (sqrt((double) pixel)*SigmaGaussian*sigma)+(TauGaussian*tau); - break; - } - case MultiplicativeGaussianNoise: - { - if (alpha <= NoiseEpsilon) - sigma=MaxRGB; - else - sigma=sqrt(-2.0*log(alpha)); - beta=(rand() & NoiseMask)/NoiseMask; - value=(double) pixel+ - pixel*SigmaMultiplicativeGaussian*sigma*cos(2.0*M_PI*beta); - break; - } - case ImpulseNoise: - { - if (alpha < (SigmaImpulse/2.0)) - value=0; - else - if (alpha >= (1.0-(SigmaImpulse/2.0))) - value=MaxRGB; - else - value=pixel; - break; - } - case LaplacianNoise: - { - if (alpha <= 0.5) - { - if (alpha <= NoiseEpsilon) - value=(double) pixel-MaxRGB; - else - value=(double) pixel+SigmaLaplacian*log(2.0*alpha); - break; - } - beta=1.0-alpha; - if (beta <= (0.5*NoiseEpsilon)) - value=(double) pixel+MaxRGB; - else - value=(double) pixel-SigmaLaplacian*log(2.0*beta); - break; - } - case PoissonNoise: - { - register int - i; - - for (i=0; alpha > exp(-SigmaPoisson*pixel); i++) - { - beta=(double) (rand() & NoiseMask)/NoiseMask; - alpha=alpha*beta; - } - value=i/SigmaPoisson; - break; - } - } - if(value < 0.0) - return(0); - if(value > MaxRGB) - return(MaxRGB); - return((unsigned int) (value+0.5)); -} - -TQImage KImageEffect::addNoise(TQImage &src, NoiseType noise_type) -{ - int x, y; - TQImage dest(src.width(), src.height(), 32); - unsigned int *destData; - - if(src.depth() > 8){ // DirectClass source image - unsigned int *srcData; - for(y=0; y < src.height(); ++y){ - srcData = (unsigned int *)src.scanLine(y); - destData = (unsigned int *)dest.scanLine(y); - for(x=0; x < src.width(); ++x){ - destData[x] = tqRgba(generateNoise(tqRed(srcData[x]), noise_type), - generateNoise(tqGreen(srcData[x]), noise_type), - generateNoise(tqBlue(srcData[x]), noise_type), - tqAlpha(srcData[x])); - } - } - } - else{ // PsudeoClass source image - unsigned char *srcData; - unsigned int *cTable = src.tqcolorTable(); - unsigned int pixel; - for(y=0; y < src.height(); ++y){ - srcData = (unsigned char *)src.scanLine(y); - destData = (unsigned int *)dest.scanLine(y); - for(x=0; x < src.width(); ++x){ - pixel = *(cTable+srcData[x]); - destData[x] = tqRgba(generateNoise(tqRed(pixel), noise_type), - generateNoise(tqGreen(pixel), noise_type), - generateNoise(tqBlue(pixel), noise_type), - tqAlpha(pixel)); - } - } - - } - return(dest); -} - -unsigned int KImageEffect::interpolateColor(TQImage *image, double x_offset, - double y_offset, - unsigned int background) -{ - double alpha, beta; - unsigned int p, q, r, s; - int x, y; - - x = (int)x_offset; - y = (int)y_offset; - if((x < -1) || (x >= image->width()) || (y < -1) || (y >= image->height())) - return(background); - if(image->depth() > 8){ - if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) { - unsigned int *t = (unsigned int *)image->scanLine(y); - p = t[x]; - q = t[x+1]; - r = t[x+image->width()]; - s = t[x+image->width()+1]; - } - else{ - unsigned int *t = (unsigned int *)image->scanLine(y); - p = background; - if((x >= 0) && (y >= 0)){ - p = t[x]; - } - q = background; - if(((x+1) < image->width()) && (y >= 0)){ - q = t[x+1]; - } - r = background; - if((x >= 0) && ((y+1) < image->height())){ - t = (unsigned int *)image->scanLine(y+1); - r = t[x+image->width()]; - } - s = background; - if(((x+1) < image->width()) && ((y+1) < image->height())){ - t = (unsigned int *)image->scanLine(y+1); - s = t[x+image->width()+1]; - } - - } - } - else{ - unsigned int *colorTable = (unsigned int *)image->tqcolorTable(); - if((x >= 0) && (y >= 0) && (x < (image->width()-1)) && (y < (image->height()-1))) { - unsigned char *t; - t = (unsigned char *)image->scanLine(y); - p = *(colorTable+t[x]); - q = *(colorTable+t[x+1]); - t = (unsigned char *)image->scanLine(y+1); - r = *(colorTable+t[x]); - s = *(colorTable+t[x+1]); - } - else{ - unsigned char *t; - p = background; - if((x >= 0) && (y >= 0)){ - t = (unsigned char *)image->scanLine(y); - p = *(colorTable+t[x]); - } - q = background; - if(((x+1) < image->width()) && (y >= 0)){ - t = (unsigned char *)image->scanLine(y); - q = *(colorTable+t[x+1]); - } - r = background; - if((x >= 0) && ((y+1) < image->height())){ - t = (unsigned char *)image->scanLine(y+1); - r = *(colorTable+t[x]); - } - s = background; - if(((x+1) < image->width()) && ((y+1) < image->height())){ - t = (unsigned char *)image->scanLine(y+1); - s = *(colorTable+t[x+1]); - } - - } - - } - x_offset -= floor(x_offset); - y_offset -= floor(y_offset); - alpha = 1.0-x_offset; - beta = 1.0-y_offset; - - return(tqRgba((unsigned char)(beta*(alpha*tqRed(p)+x_offset*tqRed(q))+y_offset*(alpha*tqRed(r)+x_offset*tqRed(s))), - (unsigned char)(beta*(alpha*tqGreen(p)+x_offset*tqGreen(q))+y_offset*(alpha*tqGreen(r)+x_offset*tqGreen(s))), - (unsigned char)(beta*(alpha*tqBlue(p)+x_offset*tqBlue(q))+y_offset*(alpha*tqBlue(r)+x_offset*tqBlue(s))), - (unsigned char)(beta*(alpha*tqAlpha(p)+x_offset*tqAlpha(q))+y_offset*(alpha*tqAlpha(r)+x_offset*tqAlpha(s))))); -} - -TQImage KImageEffect::implode(TQImage &src, double factor, - unsigned int background) -{ - double amount, distance, radius; - double x_center, x_distance, x_scale; - double y_center, y_distance, y_scale; - unsigned int *destData; - int x, y; - - TQImage dest(src.width(), src.height(), 32); - - // compute scaling factor - x_scale = 1.0; - y_scale = 1.0; - x_center = (double)0.5*src.width(); - y_center = (double)0.5*src.height(); - radius=x_center; - if(src.width() > src.height()) - y_scale = (double)src.width()/src.height(); - else if(src.width() < src.height()){ - x_scale = (double) src.height()/src.width(); - radius = y_center; - } - amount=factor/10.0; - if(amount >= 0) - amount/=10.0; - if(src.depth() > 8){ // DirectClass source image - unsigned int *srcData; - for(y=0; y < src.height(); ++y){ - srcData = (unsigned int *)src.scanLine(y); - destData = (unsigned int *)dest.scanLine(y); - y_distance=y_scale*(y-y_center); - for(x=0; x < src.width(); ++x){ - destData[x] = srcData[x]; - x_distance = x_scale*(x-x_center); - distance= x_distance*x_distance+y_distance*y_distance; - if(distance < (radius*radius)){ - double factor; - // Implode the pixel. - factor=1.0; - if(distance > 0.0) - factor= - pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount); - destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center, - factor*y_distance/y_scale+y_center, - background); - } - } - } - } - else{ // PsudeoClass source image - unsigned char *srcData; - unsigned char idx; - unsigned int *cTable = src.tqcolorTable(); - for(y=0; y < src.height(); ++y){ - srcData = (unsigned char *)src.scanLine(y); - destData = (unsigned int *)dest.scanLine(y); - y_distance=y_scale*(y-y_center); - for(x=0; x < src.width(); ++x){ - idx = srcData[x]; - destData[x] = cTable[idx]; - x_distance = x_scale*(x-x_center); - distance= x_distance*x_distance+y_distance*y_distance; - if(distance < (radius*radius)){ - double factor; - // Implode the pixel. - factor=1.0; - if(distance > 0.0) - factor= - pow(sin(0.5000000000000001*M_PI*sqrt(distance)/radius),-amount); - destData[x] = interpolateColor(&src, factor*x_distance/x_scale+x_center, - factor*y_distance/y_scale+y_center, - background); - } - } - } - - } - return(dest); -} - -TQImage KImageEffect::rotate(TQImage &img, RotateDirection r) -{ - TQImage dest; - int x, y; - if(img.depth() > 8){ - unsigned int *srcData, *destData; - switch(r){ - case Rotate90: - dest.create(img.height(), img.width(), img.depth()); - for(y=0; y < img.height(); ++y){ - srcData = (unsigned int *)img.scanLine(y); - for(x=0; x < img.width(); ++x){ - destData = (unsigned int *)dest.scanLine(x); - destData[img.height()-y-1] = srcData[x]; - } - } - break; - case Rotate180: - dest.create(img.width(), img.height(), img.depth()); - for(y=0; y < img.height(); ++y){ - srcData = (unsigned int *)img.scanLine(y); - destData = (unsigned int *)dest.scanLine(img.height()-y-1); - for(x=0; x < img.width(); ++x) - destData[img.width()-x-1] = srcData[x]; - } - break; - case Rotate270: - dest.create(img.height(), img.width(), img.depth()); - for(y=0; y < img.height(); ++y){ - srcData = (unsigned int *)img.scanLine(y); - for(x=0; x < img.width(); ++x){ - destData = (unsigned int *)dest.scanLine(img.width()-x-1); - destData[y] = srcData[x]; - } - } - break; - default: - dest = img; - break; - } - } - else{ - unsigned char *srcData, *destData; - unsigned int *srcTable, *destTable; - switch(r){ - case Rotate90: - dest.create(img.height(), img.width(), img.depth()); - dest.setNumColors(img.numColors()); - srcTable = (unsigned int *)img.tqcolorTable(); - destTable = (unsigned int *)dest.tqcolorTable(); - for(x=0; x < img.numColors(); ++x) - destTable[x] = srcTable[x]; - for(y=0; y < img.height(); ++y){ - srcData = (unsigned char *)img.scanLine(y); - for(x=0; x < img.width(); ++x){ - destData = (unsigned char *)dest.scanLine(x); - destData[img.height()-y-1] = srcData[x]; - } - } - break; - case Rotate180: - dest.create(img.width(), img.height(), img.depth()); - dest.setNumColors(img.numColors()); - srcTable = (unsigned int *)img.tqcolorTable(); - destTable = (unsigned int *)dest.tqcolorTable(); - for(x=0; x < img.numColors(); ++x) - destTable[x] = srcTable[x]; - for(y=0; y < img.height(); ++y){ - srcData = (unsigned char *)img.scanLine(y); - destData = (unsigned char *)dest.scanLine(img.height()-y-1); - for(x=0; x < img.width(); ++x) - destData[img.width()-x-1] = srcData[x]; - } - break; - case Rotate270: - dest.create(img.height(), img.width(), img.depth()); - dest.setNumColors(img.numColors()); - srcTable = (unsigned int *)img.tqcolorTable(); - destTable = (unsigned int *)dest.tqcolorTable(); - for(x=0; x < img.numColors(); ++x) - destTable[x] = srcTable[x]; - for(y=0; y < img.height(); ++y){ - srcData = (unsigned char *)img.scanLine(y); - for(x=0; x < img.width(); ++x){ - destData = (unsigned char *)dest.scanLine(img.width()-x-1); - destData[y] = srcData[x]; - } - } - break; - default: - dest = img; - break; - } - - } - return(dest); -} - -void KImageEffect::solarize(TQImage &img, double factor) -{ - int i, count; - int threshold; - unsigned int *data; - - threshold = (int)(factor*(MaxRGB+1)/100.0); - if(img.depth() < 32){ - data = (unsigned int *)img.tqcolorTable(); - count = img.numColors(); - } - else{ - data = (unsigned int *)img.bits(); - count = img.width()*img.height(); - } - for(i=0; i < count; ++i){ - data[i] = tqRgba(tqRed(data[i]) > threshold ? MaxRGB-tqRed(data[i]) : tqRed(data[i]), - tqGreen(data[i]) > threshold ? MaxRGB-tqGreen(data[i]) : tqGreen(data[i]), - tqBlue(data[i]) > threshold ? MaxRGB-tqBlue(data[i]) : tqBlue(data[i]), - tqAlpha(data[i])); - } -} - -TQImage KImageEffect::spread(TQImage &src, unsigned int amount) -{ - int quantum, x, y; - int x_distance, y_distance; - if(src.width() < 3 || src.height() < 3) - return(src); - TQImage dest(src); - dest.detach(); - quantum=(amount+1) >> 1; - if(src.depth() > 8){ // DirectClass source image - unsigned int *p, *q; - for(y=0; y < src.height(); y++){ - q = (unsigned int *)dest.scanLine(y); - for(x=0; x < src.width(); x++){ - x_distance = x + ((rand() & (amount+1))-quantum); - y_distance = y + ((rand() & (amount+1))-quantum); - x_distance = QMIN(x_distance, src.width()-1); - y_distance = QMIN(y_distance, src.height()-1); - if(x_distance < 0) - x_distance = 0; - if(y_distance < 0) - y_distance = 0; - p = (unsigned int *)src.scanLine(y_distance); - p += x_distance; - *q++=(*p); - } - } - } - else{ // PsudeoClass source image - // just do colortable values - unsigned char *p, *q; - for(y=0; y < src.height(); y++){ - q = (unsigned char *)dest.scanLine(y); - for(x=0; x < src.width(); x++){ - x_distance = x + ((rand() & (amount+1))-quantum); - y_distance = y + ((rand() & (amount+1))-quantum); - x_distance = QMIN(x_distance, src.width()-1); - y_distance = QMIN(y_distance, src.height()-1); - if(x_distance < 0) - x_distance = 0; - if(y_distance < 0) - y_distance = 0; - p = (unsigned char *)src.scanLine(y_distance); - p += x_distance; - *q++=(*p); - } - } - } - return(dest); -} - -TQImage KImageEffect::swirl(TQImage &src, double degrees, - unsigned int background) -{ - double cosine, distance, factor, radius, sine, x_center, x_distance, - x_scale, y_center, y_distance, y_scale; - int x, y; - unsigned int *q; - TQImage dest(src.width(), src.height(), 32); - - // compute scaling factor - x_center = src.width()/2.0; - y_center = src.height()/2.0; - radius = QMAX(x_center,y_center); - x_scale=1.0; - y_scale=1.0; - if(src.width() > src.height()) - y_scale=(double)src.width()/src.height(); - else if(src.width() < src.height()) - x_scale=(double)src.height()/src.width(); - degrees=DegreesToRadians(degrees); - // swirl each row - if(src.depth() > 8){ // DirectClass source image - unsigned int *p; - for(y=0; y < src.height(); y++){ - p = (unsigned int *)src.scanLine(y); - q = (unsigned int *)dest.scanLine(y); - y_distance = y_scale*(y-y_center); - for(x=0; x < src.width(); x++){ - // determine if the pixel is within an ellipse - *q=(*p); - x_distance = x_scale*(x-x_center); - distance = x_distance*x_distance+y_distance*y_distance; - if (distance < (radius*radius)){ - // swirl - factor = 1.0-sqrt(distance)/radius; - sine = sin(degrees*factor*factor); - cosine = cos(degrees*factor*factor); - *q = interpolateColor(&src, - (cosine*x_distance-sine*y_distance)/x_scale+x_center, - (sine*x_distance+cosine*y_distance)/y_scale+y_center, - background); - } - p++; - q++; - } - } - } - else{ // PsudeoClass source image - unsigned char *p; - unsigned int *cTable = (unsigned int *)src.tqcolorTable(); - for(y=0; y < src.height(); y++){ - p = (unsigned char *)src.scanLine(y); - q = (unsigned int *)dest.scanLine(y); - y_distance = y_scale*(y-y_center); - for(x=0; x < src.width(); x++){ - // determine if the pixel is within an ellipse - *q = *(cTable+(*p)); - x_distance = x_scale*(x-x_center); - distance = x_distance*x_distance+y_distance*y_distance; - if (distance < (radius*radius)){ - // swirl - factor = 1.0-sqrt(distance)/radius; - sine = sin(degrees*factor*factor); - cosine = cos(degrees*factor*factor); - *q = interpolateColor(&src, - (cosine*x_distance-sine*y_distance)/x_scale+x_center, - (sine*x_distance+cosine*y_distance)/y_scale+y_center, - background); - } - p++; - q++; - } - } - - } - return(dest); -} - -TQImage KImageEffect::wave(TQImage &src, double amplitude, double wavelength, - unsigned int background) -{ - double *sine_map; - int x, y; - unsigned int *q; - - TQImage dest(src.width(), src.height() + (int)(2*fabs(amplitude)), 32); - // allocate sine map - sine_map = (double *)malloc(dest.width()*sizeof(double)); - if(!sine_map) - return(src); - for(x=0; x < dest.width(); ++x) - sine_map[x]=fabs(amplitude)+amplitude*sin((2*M_PI*x)/wavelength); - // wave image - for(y=0; y < dest.height(); ++y){ - q = (unsigned int *)dest.scanLine(y); - for (x=0; x < dest.width(); x++){ - *q=interpolateColor(&src, x, (int)(y-sine_map[x]), background); - ++q; - } - } - free(sine_map); - return(dest); -} - -// -// The following methods work by computing a value from neighboring pixels -// (mosfet 05/26/03) -// - -// New algorithms based on ImageMagick 5.5.6 (05/26/03) - -TQImage KImageEffect::oilPaint(TQImage &src, int /*radius*/) -{ - /* binary compat method - remove me when possible! */ - return(oilPaintConvolve(src, 0)); -} - -TQImage KImageEffect::oilPaintConvolve(TQImage &src, double radius) -{ - unsigned long count /*,*histogram*/; - unsigned long histogram[256]; - unsigned int k; - int width; - int x, y, mx, my, sx, sy; - int mcx, mcy; - unsigned int *s=0, *q; - - if(src.depth() < 32) - src.convertDepth(32); - TQImage dest(src); - dest.detach(); - - width = getOptimalKernelWidth(radius, 0.5); - if(src.width() < width){ - qWarning("KImageEffect::oilPaintConvolve(): Image is smaller than radius!"); - return(dest); - } - /* - histogram = (unsigned long *)malloc(256*sizeof(unsigned long)); - if(!histogram){ - qWarning("KImageEffect::oilPaintColvolve(): Unable to allocate memory!"); - return(dest); - } - */ - unsigned int **jumpTable = (unsigned int **)src.jumpTable(); - for(y=0; y < dest.height(); ++y){ - sy = y-(width/2); - q = (unsigned int *)dest.scanLine(y); - for(x=0; x < dest.width(); ++x){ - count = 0; - memset(histogram, 0, 256*sizeof(unsigned long)); - //memset(histogram, 0, 256); - sy = y-(width/2); - for(mcy=0; mcy < width; ++mcy, ++sy){ - my = sy < 0 ? 0 : sy > src.height()-1 ? - src.height()-1 : sy; - sx = x+(-width/2); - for(mcx=0; mcx < width; ++mcx, ++sx){ - mx = sx < 0 ? 0 : sx > src.width()-1 ? - src.width()-1 : sx; - - k = intensityValue(jumpTable[my][mx]); - if(k > 255){ - qWarning("KImageEffect::oilPaintConvolve(): k is %d", - k); - k = 255; - } - histogram[k]++; - if(histogram[k] > count){ - count = histogram[k]; - s = jumpTable[my]+mx; - } - } - } - if (s) - *q++ = (*s); - } - } - /* liberateMemory((histogram); */ - return(dest); -} - -TQImage KImageEffect::charcoal(TQImage &src, double /*factor*/) -{ - /* binary compat method - remove me when possible! */ - return(charcoal(src, 0, 1)); -} - -TQImage KImageEffect::charcoal(TQImage &src, double radius, double sigma) -{ - TQImage img(edge(src, radius)); - img = blur(img, radius, sigma); - normalize(img); - img.tqinvertPixels(false); - KImageEffect::toGray(img); - return(img); -} - -void KImageEffect::normalize(TQImage &image) -{ - struct double_packet high, low, intensity, *histogram; - struct short_packet *normalize_map; - TQ_INT64 number_pixels; - int x, y; - unsigned int *p, *q; - register long i; - unsigned long threshold_intensity; - unsigned char r, g, b, a; - - if(image.depth() < 32) // result will always be 32bpp - image = image.convertDepth(32); - - histogram = (struct double_packet *) - malloc(256*sizeof(struct double_packet)); - normalize_map = (struct short_packet *) - malloc(256*sizeof(struct short_packet)); - - if(!histogram || !normalize_map){ - if(histogram) - liberateMemory(&histogram); - if(normalize_map) - liberateMemory(&normalize_map); - qWarning("KImageEffect::normalize(): Unable to allocate memory!"); - return; - } - - /* - Form histogram. - */ - memset(histogram, 0, 256*sizeof(struct double_packet)); - for(y=0; y < image.height(); ++y){ - p = (unsigned int *)image.scanLine(y); - for(x=0; x < image.width(); ++x){ - histogram[(unsigned char)(tqRed(*p))].red++; - histogram[(unsigned char)(tqGreen(*p))].green++; - histogram[(unsigned char)(tqBlue(*p))].blue++; - histogram[(unsigned char)(tqAlpha(*p))].alpha++; - p++; - } - } - - /* - Find the histogram boundaries by locating the 0.1 percent levels. - */ - number_pixels = (TQ_INT64)image.width()*image.height(); - threshold_intensity = number_pixels/1000; - - /* red */ - memset(&intensity, 0, sizeof(struct double_packet)); - memset(&high, 0, sizeof(struct double_packet)); - memset(&low, 0, sizeof(struct double_packet)); - for(high.red=255; high.red != 0; high.red--){ - intensity.red+=histogram[(unsigned char)high.red].red; - if(intensity.red > threshold_intensity) - break; - } - if(low.red == high.red){ - threshold_intensity = 0; - memset(&intensity, 0, sizeof(struct double_packet)); - for(low.red=0; low.red < 255; low.red++){ - intensity.red+=histogram[(unsigned char)low.red].red; - if(intensity.red > threshold_intensity) - break; - } - memset(&intensity, 0, sizeof(struct double_packet)); - for(high.red=255; high.red != 0; high.red--){ - intensity.red+=histogram[(unsigned char)high.red].red; - if(intensity.red > threshold_intensity) - break; - } - } - - /* green */ - memset(&intensity, 0, sizeof(struct double_packet)); - for(high.green=255; high.green != 0; high.green--){ - intensity.green+=histogram[(unsigned char)high.green].green; - if(intensity.green > threshold_intensity) - break; - } - if(low.green == high.green){ - threshold_intensity = 0; - memset(&intensity, 0, sizeof(struct double_packet)); - for(low.green=0; low.green < 255; low.green++){ - intensity.green+=histogram[(unsigned char)low.green].green; - if(intensity.green > threshold_intensity) - break; - } - memset(&intensity,0,sizeof(struct double_packet)); - for(high.green=255; high.green != 0; high.green--){ - intensity.green+=histogram[(unsigned char)high.green].green; - if(intensity.green > threshold_intensity) - break; - } - } - - /* blue */ - memset(&intensity, 0, sizeof(struct double_packet)); - for(high.blue=255; high.blue != 0; high.blue--){ - intensity.blue+=histogram[(unsigned char)high.blue].blue; - if(intensity.blue > threshold_intensity) - break; - } - if(low.blue == high.blue){ - threshold_intensity = 0; - memset(&intensity, 0, sizeof(struct double_packet)); - for(low.blue=0; low.blue < 255; low.blue++){ - intensity.blue+=histogram[(unsigned char)low.blue].blue; - if(intensity.blue > threshold_intensity) - break; - } - memset(&intensity,0,sizeof(struct double_packet)); - for(high.blue=255; high.blue != 0; high.blue--){ - intensity.blue+=histogram[(unsigned char)high.blue].blue; - if(intensity.blue > threshold_intensity) - break; - } - } - - /* alpha */ - memset(&intensity, 0, sizeof(struct double_packet)); - for(high.alpha=255; high.alpha != 0; high.alpha--){ - intensity.alpha+=histogram[(unsigned char)high.alpha].alpha; - if(intensity.alpha > threshold_intensity) - break; - } - if(low.alpha == high.alpha){ - threshold_intensity = 0; - memset(&intensity, 0, sizeof(struct double_packet)); - for(low.alpha=0; low.alpha < 255; low.alpha++){ - intensity.alpha+=histogram[(unsigned char)low.alpha].alpha; - if(intensity.alpha > threshold_intensity) - break; - } - memset(&intensity,0,sizeof(struct double_packet)); - for(high.alpha=255; high.alpha != 0; high.alpha--){ - intensity.alpha+=histogram[(unsigned char)high.alpha].alpha; - if(intensity.alpha > threshold_intensity) - break; - } - } - liberateMemory(&histogram); - - /* - Stretch the histogram to create the normalized image mapping. - */ - - // should the maxes be 65535? - memset(normalize_map, 0 ,256*sizeof(struct short_packet)); - for(i=0; i <= (long) 255; i++){ - if(i < (long) low.red) - normalize_map[i].red=0; - else if (i > (long) high.red) - normalize_map[i].red=65535; - else if (low.red != high.red) - normalize_map[i].red = - (unsigned short)((65535*(i-low.red))/(high.red-low.red)); - - if(i < (long) low.green) - normalize_map[i].green=0; - else if (i > (long) high.green) - normalize_map[i].green=65535; - else if (low.green != high.green) - normalize_map[i].green = - (unsigned short)((65535*(i-low.green))/(high.green-low.green)); - - if(i < (long) low.blue) - normalize_map[i].blue=0; - else if (i > (long) high.blue) - normalize_map[i].blue=65535; - else if (low.blue != high.blue) - normalize_map[i].blue = - (unsigned short)((65535*(i-low.blue))/(high.blue-low.blue)); - - if(i < (long) low.alpha) - normalize_map[i].alpha=0; - else if (i > (long) high.alpha) - normalize_map[i].alpha=65535; - else if (low.alpha != high.alpha) - normalize_map[i].alpha = - (unsigned short)((65535*(i-low.alpha))/(high.alpha-low.alpha)); - - } - - for(y=0; y < image.height(); ++y){ - q = (unsigned int *)image.scanLine(y); - for(x=0; x < image.width(); ++x){ - if(low.red != high.red) - r = (normalize_map[(unsigned short)(tqRed(q[x]))].red)/257; - else - r = tqRed(q[x]); - if(low.green != high.green) - g = (normalize_map[(unsigned short)(tqGreen(q[x]))].green)/257; - else - g = tqGreen(q[x]); - if(low.blue != high.blue) - b = (normalize_map[(unsigned short)(tqBlue(q[x]))].blue)/257; - else - b = tqBlue(q[x]); - if(low.alpha != high.alpha) - a = (normalize_map[(unsigned short)(tqAlpha(q[x]))].alpha)/257; - else - a = tqAlpha(q[x]); - q[x] = tqRgba(r, g, b, a); - } - } - liberateMemory(&normalize_map); -} - -void KImageEffect::equalize(TQImage &image) -{ - struct double_packet high, low, intensity, *map, *histogram; - struct short_packet *equalize_map; - int x, y; - unsigned int *p, *q; - long i; - unsigned char r, g, b, a; - - if(image.depth() < 32) // result will always be 32bpp - image = image.convertDepth(32); - - histogram=(struct double_packet *) malloc(256*sizeof(struct double_packet)); - map=(struct double_packet *) malloc(256*sizeof(struct double_packet)); - equalize_map=(struct short_packet *)malloc(256*sizeof(struct short_packet)); - if(!histogram || !map || !equalize_map){ - if(histogram) - liberateMemory(&histogram); - if(map) - liberateMemory(&map); - if(equalize_map) - liberateMemory(&equalize_map); - qWarning("KImageEffect::equalize(): Unable to allocate memory!"); - return; - } - - /* - Form histogram. - */ - memset(histogram, 0, 256*sizeof(struct double_packet)); - for(y=0; y < image.height(); ++y){ - p = (unsigned int *)image.scanLine(y); - for(x=0; x < image.width(); ++x){ - histogram[(unsigned char)(tqRed(*p))].red++; - histogram[(unsigned char)(tqGreen(*p))].green++; - histogram[(unsigned char)(tqBlue(*p))].blue++; - histogram[(unsigned char)(tqAlpha(*p))].alpha++; - p++; - } - } - /* - Integrate the histogram to get the equalization map. - */ - memset(&intensity, 0 ,sizeof(struct double_packet)); - for(i=0; i <= 255; ++i){ - intensity.red += histogram[i].red; - intensity.green += histogram[i].green; - intensity.blue += histogram[i].blue; - intensity.alpha += histogram[i].alpha; - map[i]=intensity; - } - low=map[0]; - high=map[255]; - memset(equalize_map, 0, 256*sizeof(short_packet)); - for(i=0; i <= 255; ++i){ - if(high.red != low.red) - equalize_map[i].red=(unsigned short) - ((65535*(map[i].red-low.red))/(high.red-low.red)); - if(high.green != low.green) - equalize_map[i].green=(unsigned short) - ((65535*(map[i].green-low.green))/(high.green-low.green)); - if(high.blue != low.blue) - equalize_map[i].blue=(unsigned short) - ((65535*(map[i].blue-low.blue))/(high.blue-low.blue)); - if(high.alpha != low.alpha) - equalize_map[i].alpha=(unsigned short) - ((65535*(map[i].alpha-low.alpha))/(high.alpha-low.alpha)); - } - liberateMemory(&histogram); - liberateMemory(&map); - - /* - Stretch the histogram. - */ - for(y=0; y < image.height(); ++y){ - q = (unsigned int *)image.scanLine(y); - for(x=0; x < image.width(); ++x){ - if(low.red != high.red) - r = (equalize_map[(unsigned short)(tqRed(q[x]))].red/257); - else - r = tqRed(q[x]); - if(low.green != high.green) - g = (equalize_map[(unsigned short)(tqGreen(q[x]))].green/257); - else - g = tqGreen(q[x]); - if(low.blue != high.blue) - b = (equalize_map[(unsigned short)(tqBlue(q[x]))].blue/257); - else - b = tqBlue(q[x]); - if(low.alpha != high.alpha) - a = (equalize_map[(unsigned short)(tqAlpha(q[x]))].alpha/257); - else - a = tqAlpha(q[x]); - q[x] = tqRgba(r, g, b, a); - } - } - liberateMemory(&equalize_map); - -} - -TQImage KImageEffect::edge(TQImage &image, double radius) -{ - double *kernel; - int width; - register long i; - TQImage dest; - - if(radius == 50.0){ - /* For binary compatability! Remove me when possible! This used to - * take a different parameter, a factor, and this was the default - * value */ - radius = 0.0; - } - - width = getOptimalKernelWidth(radius, 0.5); - if(image.width() < width || image.height() < width){ - qWarning("KImageEffect::edge(): Image is smaller than radius!"); - return(dest); - } - kernel= (double *)malloc(width*width*sizeof(double)); - if(!kernel){ - qWarning("KImageEffect::edge(): Unable to allocate memory!"); - return(dest); - } - for(i=0; i < (width*width); i++) - kernel[i]=(-1.0); - kernel[i/2]=width*width-1.0; - convolveImage(&image, &dest, width, kernel); - free(kernel); - return(dest); -} - -TQImage KImageEffect::emboss(TQImage &src) -{ - /* binary compat method - remove me when possible! */ - return(emboss(src, 0, 1)); -} - -TQImage KImageEffect::emboss(TQImage &image, double radius, double sigma) -{ - double alpha, *kernel; - int j, width; - register long i, u, v; - TQImage dest; - - if(sigma == 0.0){ - qWarning("KImageEffect::emboss(): Zero sigma is not permitted!"); - return(dest); - } - - width = getOptimalKernelWidth(radius, sigma); - if(image.width() < width || image.height() < width){ - qWarning("KImageEffect::emboss(): Image is smaller than radius!"); - return(dest); - } - kernel= (double *)malloc(width*width*sizeof(double)); - if(!kernel){ - qWarning("KImageEffect::emboss(): Unable to allocate memory!"); - return(dest); - } - if(image.depth() < 32) - image = image.convertDepth(32); - - i=0; - j=width/2; - for(v=(-width/2); v <= (width/2); v++){ - for(u=(-width/2); u <= (width/2); u++){ - alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma)); - kernel[i]=((u < 0) || (v < 0) ? -8.0 : 8.0)*alpha/ - (2.0*MagickPI*sigma*sigma); - if (u == j) - kernel[i]=0.0; - i++; - } - j--; - } - convolveImage(&image, &dest, width, kernel); - liberateMemory(&kernel); - - equalize(dest); - return(dest); -} - -void KImageEffect::blurScanLine(double *kernel, int width, - unsigned int *src, unsigned int *dest, - int columns) -{ - register double *p; - unsigned int *q; - register int x; - register long i; - double red, green, blue, alpha; - double scale = 0.0; - - if(width > columns){ - for(x=0; x < columns; ++x){ - scale = 0.0; - red = blue = green = alpha = 0.0; - p = kernel; - q = src; - for(i=0; i < columns; ++i){ - if((i >= (x-width/2)) && (i <= (x+width/2))){ - red += (*p)*(tqRed(*q)*257); - green += (*p)*(tqGreen(*q)*257); - blue += (*p)*(tqBlue(*q)*257); - alpha += (*p)*(tqAlpha(*q)*257); - } - if(((i+width/2-x) >= 0) && ((i+width/2-x) < width)) - scale+=kernel[i+width/2-x]; - p++; - q++; - } - scale = 1.0/scale; - red = scale*(red+0.5); - green = scale*(green+0.5); - blue = scale*(blue+0.5); - alpha = scale*(alpha+0.5); - - red = red < 0 ? 0 : red > 65535 ? 65535 : red; - green = green < 0 ? 0 : green > 65535 ? 65535 : green; - blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; - alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; - - dest[x] = tqRgba((unsigned char)(red/257UL), - (unsigned char)(green/257UL), - (unsigned char)(blue/257UL), - (unsigned char)(alpha/257UL)); - } - return; - } - - for(x=0; x < width/2; ++x){ - scale = 0.0; - red = blue = green = alpha = 0.0; - p = kernel+width/2-x; - q = src; - for(i=width/2-x; i < width; ++i){ - red += (*p)*(tqRed(*q)*257); - green += (*p)*(tqGreen(*q)*257); - blue += (*p)*(tqBlue(*q)*257); - alpha += (*p)*(tqAlpha(*q)*257); - scale += (*p); - p++; - q++; - } - scale=1.0/scale; - - red = scale*(red+0.5); - green = scale*(green+0.5); - blue = scale*(blue+0.5); - alpha = scale*(alpha+0.5); - - red = red < 0 ? 0 : red > 65535 ? 65535 : red; - green = green < 0 ? 0 : green > 65535 ? 65535 : green; - blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; - alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; - - dest[x] = tqRgba((unsigned char)(red/257UL), - (unsigned char)(green/257UL), - (unsigned char)(blue/257UL), - (unsigned char)(alpha/257UL)); - } - - for(; x < columns-width/2; ++x){ - red = blue = green = alpha = 0.0; - p = kernel; - q = src+(x-width/2); - for (i=0; i < (long) width; ++i){ - red += (*p)*(tqRed(*q)*257); - green += (*p)*(tqGreen(*q)*257); - blue += (*p)*(tqBlue(*q)*257); - alpha += (*p)*(tqAlpha(*q)*257); - p++; - q++; - } - red = scale*(red+0.5); - green = scale*(green+0.5); - blue = scale*(blue+0.5); - alpha = scale*(alpha+0.5); - - red = red < 0 ? 0 : red > 65535 ? 65535 : red; - green = green < 0 ? 0 : green > 65535 ? 65535 : green; - blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; - alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; - - dest[x] = tqRgba((unsigned char)(red/257UL), - (unsigned char)(green/257UL), - (unsigned char)(blue/257UL), - (unsigned char)(alpha/257UL)); - } - - for(; x < columns; ++x){ - red = blue = green = alpha = 0.0; - scale=0; - p = kernel; - q = src+(x-width/2); - for(i=0; i < columns-x+width/2; ++i){ - red += (*p)*(tqRed(*q)*257); - green += (*p)*(tqGreen(*q)*257); - blue += (*p)*(tqBlue(*q)*257); - alpha += (*p)*(tqAlpha(*q)*257); - scale += (*p); - p++; - q++; - } - scale=1.0/scale; - red = scale*(red+0.5); - green = scale*(green+0.5); - blue = scale*(blue+0.5); - alpha = scale*(alpha+0.5); - - red = red < 0 ? 0 : red > 65535 ? 65535 : red; - green = green < 0 ? 0 : green > 65535 ? 65535 : green; - blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue; - alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha; - - dest[x] = tqRgba((unsigned char)(red/257UL), - (unsigned char)(green/257UL), - (unsigned char)(blue/257UL), - (unsigned char)(alpha/257UL)); - } -} - -int KImageEffect::getBlurKernel(int width, double sigma, double **kernel) -{ -#define KernelRank 3 - double alpha, normalize; - register long i; - int bias; - - assert(sigma != 0.0); - if(width == 0) - width = 3; - *kernel=(double *)malloc(width*sizeof(double)); - if(*kernel == (double *)NULL) - return(0); - memset(*kernel, 0, width*sizeof(double)); - bias = KernelRank*width/2; - for(i=(-bias); i <= bias; i++){ - alpha=exp(-((double) i*i)/(2.0*KernelRank*KernelRank*sigma*sigma)); - (*kernel)[(i+bias)/KernelRank]+=alpha/(MagickSQ2PI*sigma); - } - normalize=0; - for(i=0; i < width; i++) - normalize+=(*kernel)[i]; - for(i=0; i < width; i++) - (*kernel)[i]/=normalize; - - return(width); -} - -TQImage KImageEffect::blur(TQImage &src, double /*factor*/) -{ - /* binary compat method - remove me when possible! */ - return(blur(src, 0, 1)); -} - -TQImage KImageEffect::blur(TQImage &src, double radius, double sigma) -{ - double *kernel; - TQImage dest; - int width; - int x, y; - unsigned int *scanline, *temp; - unsigned int *p, *q; - - if(sigma == 0.0){ - qWarning("KImageEffect::blur(): Zero sigma is not permitted!"); - return(dest); - } - if(src.depth() < 32) - src = src.convertDepth(32); - - kernel=(double *) NULL; - if(radius > 0) - width=getBlurKernel((int) (2*ceil(radius)+1),sigma,&kernel); - else{ - double *last_kernel; - last_kernel=(double *) NULL; - width=getBlurKernel(3,sigma,&kernel); - - while ((long) (MaxRGB*kernel[0]) > 0){ - if(last_kernel != (double *)NULL){ - liberateMemory(&last_kernel); - } - last_kernel=kernel; - kernel = (double *)NULL; - width = getBlurKernel(width+2, sigma, &kernel); - } - if(last_kernel != (double *) NULL){ - liberateMemory(&kernel); - width-=2; - kernel = last_kernel; - } - } - - if(width < 3){ - qWarning("KImageEffect::blur(): Kernel radius is too small!"); - liberateMemory(&kernel); - return(dest); - } - - dest.create(src.width(), src.height(), 32); - - // Horizontal convolution - scanline = (unsigned int *)malloc(sizeof(unsigned int)*src.height()); - temp = (unsigned int *)malloc(sizeof(unsigned int)*src.height()); - for(y=0; y < src.height(); ++y){ - p = (unsigned int *)src.scanLine(y); - q = (unsigned int *)dest.scanLine(y); - blurScanLine(kernel, width, p, q, src.width()); - } - - TQImage partial = dest; - - // Vertical convolution - unsigned int **srcTable = (unsigned int **)partial.jumpTable(); - unsigned int **destTable = (unsigned int **)dest.jumpTable(); - for(x=0; x < partial.width(); ++x){ - for(y=0; y < partial.height(); ++y){ - scanline[y] = srcTable[y][x]; - } - blurScanLine(kernel, width, scanline, temp, partial.height()); - for(y=0; y < partial.height(); ++y){ - destTable[y][x] = temp[y]; - } - } - free(scanline); - free(temp); - free(kernel); - return(dest); -} - -bool KImageEffect::convolveImage(TQImage *image, TQImage *dest, - const unsigned int order, - const double *kernel) -{ - long width; - double red, green, blue, alpha; - double normalize, *normal_kernel; - register const double *k; - register unsigned int *q; - int x, y, mx, my, sx, sy; - long i; - int mcx, mcy; - - width = order; - if((width % 2) == 0){ - qWarning("KImageEffect: Kernel width must be an odd number!"); - return(false); - } - normal_kernel = (double *)malloc(width*width*sizeof(double)); - if(!normal_kernel){ - qWarning("KImageEffect: Unable to allocate memory!"); - return(false); - } - dest->reset(); - dest->create(image->width(), image->height(), 32); - if(image->depth() < 32) - *image = image->convertDepth(32); - - normalize=0.0; - for(i=0; i < (width*width); i++) - normalize += kernel[i]; - if(fabs(normalize) <= MagickEpsilon) - normalize=1.0; - normalize=1.0/normalize; - for(i=0; i < (width*width); i++) - normal_kernel[i] = normalize*kernel[i]; - - unsigned int **jumpTable = (unsigned int **)image->jumpTable(); - for(y=0; y < dest->height(); ++y){ - sy = y-(width/2); - q = (unsigned int *)dest->scanLine(y); - for(x=0; x < dest->width(); ++x){ - k = normal_kernel; - red = green = blue = alpha = 0; - sy = y-(width/2); - for(mcy=0; mcy < width; ++mcy, ++sy){ - my = sy < 0 ? 0 : sy > image->height()-1 ? - image->height()-1 : sy; - sx = x+(-width/2); - for(mcx=0; mcx < width; ++mcx, ++sx){ - mx = sx < 0 ? 0 : sx > image->width()-1 ? - image->width()-1 : sx; - red += (*k)*(tqRed(jumpTable[my][mx])*257); - green += (*k)*(tqGreen(jumpTable[my][mx])*257); - blue += (*k)*(tqBlue(jumpTable[my][mx])*257); - alpha += (*k)*(tqAlpha(jumpTable[my][mx])*257); - ++k; - } - } - - red = red < 0 ? 0 : red > 65535 ? 65535 : red+0.5; - green = green < 0 ? 0 : green > 65535 ? 65535 : green+0.5; - blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue+0.5; - alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha+0.5; - - *q++ = tqRgba((unsigned char)(red/257UL), - (unsigned char)(green/257UL), - (unsigned char)(blue/257UL), - (unsigned char)(alpha/257UL)); - } - } - free(normal_kernel); - return(true); - -} - -int KImageEffect::getOptimalKernelWidth(double radius, double sigma) -{ - double normalize, value; - long width; - register long u; - - assert(sigma != 0.0); - if(radius > 0.0) - return((int)(2.0*ceil(radius)+1.0)); - for(width=5; ;){ - normalize=0.0; - for(u=(-width/2); u <= (width/2); u++) - normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma); - u=width/2; - value=exp(-((double) u*u)/(2.0*sigma*sigma))/(MagickSQ2PI*sigma)/normalize; - if((long)(65535*value) <= 0) - break; - width+=2; - } - return((int)width-2); -} - -TQImage KImageEffect::sharpen(TQImage &src, double /*factor*/) -{ - /* binary compat method - remove me when possible! */ - return(sharpen(src, 0, 1)); -} - -TQImage KImageEffect::sharpen(TQImage &image, double radius, double sigma) -{ - double alpha, normalize, *kernel; - int width; - register long i, u, v; - TQImage dest; - - if(sigma == 0.0){ - qWarning("KImageEffect::sharpen(): Zero sigma is not permitted!"); - return(dest); - } - width = getOptimalKernelWidth(radius, sigma); - if(image.width() < width){ - qWarning("KImageEffect::sharpen(): Image is smaller than radius!"); - return(dest); - } - kernel = (double *)malloc(width*width*sizeof(double)); - if(!kernel){ - qWarning("KImageEffect::sharpen(): Unable to allocate memory!"); - return(dest); - } - - i = 0; - normalize=0.0; - for(v=(-width/2); v <= (width/2); v++){ - for(u=(-width/2); u <= (width/2); u++){ - alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma)); - kernel[i]=alpha/(2.0*MagickPI*sigma*sigma); - normalize+=kernel[i]; - i++; - } - } - kernel[i/2]=(-2.0)*normalize; - convolveImage(&image, &dest, width, kernel); - free(kernel); - return(dest); -} - -// End of new algorithms - -TQImage KImageEffect::shade(TQImage &src, bool color_shading, double azimuth, - double elevation) -{ - struct PointInfo{ - double x, y, z; - }; - - double distance, normal_distance, shade; - int x, y; - - struct PointInfo light, normal; - - unsigned int *q; - - TQImage dest(src.width(), src.height(), 32); - - azimuth = DegreesToRadians(azimuth); - elevation = DegreesToRadians(elevation); - light.x = MaxRGB*cos(azimuth)*cos(elevation); - light.y = MaxRGB*sin(azimuth)*cos(elevation); - light.z = MaxRGB*sin(elevation); - normal.z= 2*MaxRGB; // constant Z of surface normal - - if(src.depth() > 8){ // DirectClass source image - unsigned int *p, *s0, *s1, *s2; - for(y=0; y < src.height(); ++y){ - p = (unsigned int *)src.scanLine(QMIN(QMAX(y-1,0),src.height()-3)); - q = (unsigned int *)dest.scanLine(y); - // shade this row of pixels. - *q++=(*(p+src.width())); - p++; - s0 = p; - s1 = p + src.width(); - s2 = p + 2*src.width(); - for(x=1; x < src.width()-1; ++x){ - // determine the surface normal and compute shading. - normal.x=intensityValue(*(s0-1))+intensityValue(*(s1-1))+intensityValue(*(s2-1))- - (double) intensityValue(*(s0+1))-(double) intensityValue(*(s1+1))- - (double) intensityValue(*(s2+1)); - normal.y=intensityValue(*(s2-1))+intensityValue(*s2)+intensityValue(*(s2+1))- - (double) intensityValue(*(s0-1))-(double) intensityValue(*s0)- - (double) intensityValue(*(s0+1)); - if((normal.x == 0) && (normal.y == 0)) - shade=light.z; - else{ - shade=0.0; - distance=normal.x*light.x+normal.y*light.y+normal.z*light.z; - if (distance > 0.0){ - normal_distance= - normal.x*normal.x+normal.y*normal.y+normal.z*normal.z; - if(fabs(normal_distance) > 0.0000001) - shade=distance/sqrt(normal_distance); - } - } - if(!color_shading){ - *q = tqRgba((unsigned char)(shade), - (unsigned char)(shade), - (unsigned char)(shade), - tqAlpha(*s1)); - } - else{ - *q = tqRgba((unsigned char)((shade*tqRed(*s1))/(MaxRGB+1)), - (unsigned char)((shade*tqGreen(*s1))/(MaxRGB+1)), - (unsigned char)((shade*tqBlue(*s1))/(MaxRGB+1)), - tqAlpha(*s1)); - } - ++s0; - ++s1; - ++s2; - q++; - } - *q++=(*s1); - } - } - else{ // PsudeoClass source image - unsigned char *p, *s0, *s1, *s2; - int scanLineIdx; - unsigned int *cTable = (unsigned int *)src.tqcolorTable(); - for(y=0; y < src.height(); ++y){ - scanLineIdx = QMIN(QMAX(y-1,0),src.height()-3); - p = (unsigned char *)src.scanLine(scanLineIdx); - q = (unsigned int *)dest.scanLine(y); - // shade this row of pixels. - s0 = p; - s1 = (unsigned char *) src.scanLine(scanLineIdx+1); - s2 = (unsigned char *) src.scanLine(scanLineIdx+2); - *q++=(*(cTable+(*s1))); - ++p; - ++s0; - ++s1; - ++s2; - for(x=1; x < src.width()-1; ++x){ - // determine the surface normal and compute shading. - normal.x=intensityValue(*(cTable+(*(s0-1))))+intensityValue(*(cTable+(*(s1-1))))+intensityValue(*(cTable+(*(s2-1))))- - (double) intensityValue(*(cTable+(*(s0+1))))-(double) intensityValue(*(cTable+(*(s1+1))))- - (double) intensityValue(*(cTable+(*(s2+1)))); - normal.y=intensityValue(*(cTable+(*(s2-1))))+intensityValue(*(cTable+(*s2)))+intensityValue(*(cTable+(*(s2+1))))- - (double) intensityValue(*(cTable+(*(s0-1))))-(double) intensityValue(*(cTable+(*s0)))- - (double) intensityValue(*(cTable+(*(s0+1)))); - if((normal.x == 0) && (normal.y == 0)) - shade=light.z; - else{ - shade=0.0; - distance=normal.x*light.x+normal.y*light.y+normal.z*light.z; - if (distance > 0.0){ - normal_distance= - normal.x*normal.x+normal.y*normal.y+normal.z*normal.z; - if(fabs(normal_distance) > 0.0000001) - shade=distance/sqrt(normal_distance); - } - } - if(!color_shading){ - *q = tqRgba((unsigned char)(shade), - (unsigned char)(shade), - (unsigned char)(shade), - tqAlpha(*(cTable+(*s1)))); - } - else{ - *q = tqRgba((unsigned char)((shade*tqRed(*(cTable+(*s1))))/(MaxRGB+1)), - (unsigned char)((shade*tqGreen(*(cTable+(*s1))))/(MaxRGB+1)), - (unsigned char)((shade*tqBlue(*(cTable+(*s1))))/(MaxRGB+1)), - tqAlpha(*s1)); - } - ++s0; - ++s1; - ++s2; - q++; - } - *q++=(*(cTable+(*s1))); - } - } - return(dest); -} - -// High quality, expensive HSV contrast. You can do a faster one by just -// taking a grayscale threshold (ie: 128) and incrementing RGB color -// channels above it and decrementing those below it, but this gives much -// better results. (mosfet 12/28/01) -void KImageEffect::contrastHSV(TQImage &img, bool sharpen) -{ - int i, sign; - unsigned int *data; - int count; - double brightness, scale, theta; - TQColor c; - int h, s, v; - - sign = sharpen ? 1 : -1; - scale=0.5000000000000001; - if(img.depth() > 8){ - count = img.width()*img.height(); - data = (unsigned int *)img.bits(); - } - else{ - count = img.numColors(); - data = (unsigned int *)img.tqcolorTable(); - } - for(i=0; i < count; ++i){ - c.setRgb(data[i]); - c.hsv(&h, &s, &v); - brightness = v/255.0; - theta=(brightness-0.5)*M_PI; - brightness+=scale*(((scale*((sin(theta)+1.0)))-brightness)*sign); - if (brightness > 1.0) - brightness=1.0; - else - if (brightness < 0) - brightness=0.0; - v = (int)(brightness*255); - c.setHsv(h, s, v); - data[i] = tqRgba(c.red(), c.green(), c.blue(), tqAlpha(data[i])); - } -} - - -struct BumpmapParams { - BumpmapParams( double bm_azimuth, double bm_elevation, - int bm_depth, KImageEffect::BumpmapType bm_type, - bool invert ) { - /* Convert to radians */ - double azimuth = DegreesToRadians( bm_azimuth ); - double elevation = DegreesToRadians( bm_elevation ); - - /* Calculate the light vector */ - lx = (int)( cos(azimuth) * cos(elevation) * 255.0 ); - ly = (int)( sin(azimuth) * cos(elevation) * 255.0 ); - int lz = (int)( sin(elevation) * 255.0 ); - - /* Calculate constant Z component of surface normal */ - int nz = (6 * 255) / bm_depth; - nz2 = nz * nz; - nzlz = nz * lz; - - /* Optimize for vertical normals */ - background = lz; - - /* Calculate darkness compensation factor */ - compensation = sin(elevation); - - /* Create look-up table for map type */ - for (int i = 0; i < 256; i++) - { - double n = 0; - switch (bm_type) - { - case KImageEffect::Spherical: - n = i / 255.0 - 1.0; - lut[i] = (int) (255.0 * sqrt(1.0 - n * n) + 0.5); - break; - - case KImageEffect::Sinuosidal: - n = i / 255.0; - lut[i] = (int) (255.0 * (sin((-M_PI / 2.0) + M_PI * n) + 1.0) / - 2.0 + 0.5); - break; - - case KImageEffect::Linear: - default: - lut[i] = i; - } - - if (invert) - lut[i] = 255 - lut[i]; - } - } - int lx, ly; - int nz2, nzlz; - int background; - double compensation; - uchar lut[256]; -}; - - -static void bumpmap_convert_row( uint *row, - int width, - int bpp, - int has_alpha, - uchar *lut, - int waterlevel ) -{ - uint *p; - - p = row; - - has_alpha = has_alpha ? 1 : 0; - - if (bpp >= 3) - for (; width; width--) - { - if (has_alpha) { - unsigned int idx = (unsigned int)(intensityValue( *row ) + 0.5); - *p++ = lut[(unsigned int) ( waterlevel + - ( ( idx - - waterlevel) * tqBlue( *row )) / 255.0 )]; - } else { - unsigned int idx = (unsigned int)(intensityValue( *row ) + 0.5); - *p++ = lut[idx]; - } - - ++row; - } -} - -static void bumpmap_row( uint *src, - uint *dest, - int width, - int bpp, - int has_alpha, - uint *bm_row1, - uint *bm_row2, - uint *bm_row3, - int bm_width, - int bm_xofs, - bool tiled, - bool row_in_bumpmap, - int ambient, - bool compensate, - BumpmapParams *params ) -{ - int xofs1, xofs2, xofs3; - int shade; - int ndotl; - int nx, ny; - int x; - int tmp; - - tmp = bm_xofs; - xofs2 = MOD(tmp, bm_width); - - for (x = 0; x < width; x++) - { - /* Calculate surface normal from bump map */ - - if (tiled || (row_in_bumpmap && - x >= - tmp && x < - tmp + bm_width)) { - if (tiled) { - xofs1 = MOD(xofs2 - 1, bm_width); - xofs3 = MOD(xofs2 + 1, bm_width); - } else { - xofs1 = FXCLAMP(xofs2 - 1, 0, bm_width - 1); - xofs3 = FXCLAMP(xofs2 + 1, 0, bm_width - 1); - } - nx = (bm_row1[xofs1] + bm_row2[xofs1] + bm_row3[xofs1] - - bm_row1[xofs3] - bm_row2[xofs3] - bm_row3[xofs3]); - ny = (bm_row3[xofs1] + bm_row3[xofs2] + bm_row3[xofs3] - - bm_row1[xofs1] - bm_row1[xofs2] - bm_row1[xofs3]); - } else { - nx = ny = 0; - } - - /* Shade */ - - if ((nx == 0) && (ny == 0)) - shade = params->background; - else { - ndotl = nx * params->lx + ny * params->ly + params->nzlz; - - if (ndotl < 0) - shade = (int)( params->compensation * ambient ); - else { - shade = (int)( ndotl / sqrt(double(nx * nx + ny * ny + params->nz2)) ); - - shade = (int)( shade + QMAX(0.0, (255 * params->compensation - shade)) * - ambient / 255 ); - } - } - - /* Paint */ - - /** - * NOTE: if we want to work with non-32bit images the alpha handling would - * also change - */ - if (compensate) { - int red = (int)((tqRed( *src ) * shade) / (params->compensation * 255)); - int green = (int)((tqGreen( *src ) * shade) / (params->compensation * 255)); - int blue = (int)((tqBlue( *src ) * shade) / (params->compensation * 255)); - int alpha = (int)((tqAlpha( *src ) * shade) / (params->compensation * 255)); - ++src; - *dest++ = tqRgba( red, green, blue, alpha ); - } else { - int red = tqRed( *src ) * shade / 255; - int green = tqGreen( *src ) * shade / 255; - int blue = tqBlue( *src ) * shade / 255; - int alpha = tqAlpha( *src ) * shade / 255; - ++src; - *dest++ = tqRgba( red, green, blue, alpha ); - } - - /* Next pixel */ - - if (++xofs2 == bm_width) - xofs2 = 0; - } -} - -/** - * A bumpmapping algorithm. - * - * @param img the image you want bumpmap - * @param map the map used - * @param azimuth azimuth - * @param elevation elevation - * @param depth depth (not the depth of the image, but of the map) - * @param xofs X offset - * @param yofs Y offset - * @param waterlevel level that full transparency should represent - * @param ambient ambient lighting factor - * @param compensate compensate for darkening - * @param invert invert bumpmap - * @param type type of the bumpmap - * - * @return The destination image (dst) containing the result. - * @author Zack Rusin <zack@kde.org> - */ -TQImage KImageEffect::bumpmap(TQImage &img, TQImage &map, double azimuth, double elevation, - int depth, int xofs, int yofs, int waterlevel, - int ambient, bool compensate, bool invert, - BumpmapType type, bool tiled) -{ - TQImage dst; - - if ( img.depth() != 32 || img.depth() != 32 ) { - qWarning( "Bump-mapping effect works only with 32 bit images"); - return dst; - } - - dst.create( img.width(), img.height(), img.depth() ); - int bm_width = map.width(); - int bm_height = map.height(); - int bm_bpp = map.depth(); - int bm_has_alpha = map.hasAlphaBuffer(); - - int yofs1, yofs2, yofs3; - - if ( tiled ) { - yofs2 = MOD( yofs, bm_height ); - yofs1 = MOD( yofs2 - 1, bm_height); - yofs3 = MOD( yofs2 + 1, bm_height); - } else { - yofs1 = 0; - yofs2 = 0; - yofs3 = FXCLAMP( yofs2+1, 0, bm_height - 1 ); - } - - BumpmapParams params( azimuth, elevation, depth, type, invert ); - - uint* bm_row1 = (unsigned int*)map.scanLine( yofs1 ); - uint* bm_row2 = (unsigned int*)map.scanLine( yofs2 ); - uint* bm_row3 = (unsigned int*)map.scanLine( yofs3 ); - - bumpmap_convert_row( bm_row1, bm_width, bm_bpp, bm_has_alpha, params.lut, waterlevel ); - bumpmap_convert_row( bm_row2, bm_width, bm_bpp, bm_has_alpha, params.lut, waterlevel ); - bumpmap_convert_row( bm_row3, bm_width, bm_bpp, bm_has_alpha, params.lut, waterlevel ); - - for (int y = 0; y < img.height(); ++y) - { - int row_in_bumpmap = (y >= - yofs && y < - yofs + bm_height); - - uint* src_row = (unsigned int*)img.scanLine( y ); - uint* dest_row = (unsigned int*)dst.scanLine( y ); - - bumpmap_row( src_row, dest_row, img.width(), img.depth(), img.hasAlphaBuffer(), - bm_row1, bm_row2, bm_row3, bm_width, xofs, - tiled, - row_in_bumpmap, ambient, compensate, - ¶ms ); - - /* Next line */ - - if (tiled || row_in_bumpmap) - { - uint* bm_tmprow = bm_row1; - bm_row1 = bm_row2; - bm_row2 = bm_row3; - bm_row3 = bm_tmprow; - - if (++yofs2 == bm_height) - yofs2 = 0; - - if (tiled) - yofs3 = MOD(yofs2 + 1, bm_height); - else - yofs3 = FXCLAMP(yofs2 + 1, 0, bm_height - 1); - - bm_row3 = (unsigned int*)map.scanLine( yofs3 ); - bumpmap_convert_row( bm_row3, bm_width, bm_bpp, bm_has_alpha, - params.lut, waterlevel ); - } - } - return dst; -} - -/** - * Convert an image with standard alpha to premultiplied alpha - * - * @param img the image you want convert - * - * @return The destination image (dst) containing the result. - * @author Timothy Pearson <kb9vqf@pearsoncomputing.net> - */ -TQImage KImageEffect::convertToPremultipliedAlpha(TQImage input) { - TQImage alphaImage = input; - if (!alphaImage.isNull()) alphaImage = alphaImage.convertDepth( 32 ); - - int w = alphaImage.width(); - int h = alphaImage.height(); - - register int r; - register int g; - register int b; - register int a; - register float alpha_adjust; - register TQRgb l; - TQRgb *ls; - for (int y = 0; y < h; ++y) { - ls = (TQRgb *)alphaImage.scanLine( y ); - for (int x = 0; x < w; ++x) { - l = ls[x]; - alpha_adjust = (tqAlpha( l )/255.0); - r = int( tqRed( l ) * alpha_adjust ); - g = int( tqGreen( l ) * alpha_adjust ); - b = int( tqBlue( l ) * alpha_adjust ); - a = int( tqAlpha( l ) * 1.0 ); - ls[x] = tqRgba( r, g, b, a ); - } - } - return alphaImage; -}
\ No newline at end of file diff --git a/kdefx/kimageeffect.h b/kdefx/kimageeffect.h deleted file mode 100644 index 8d73e5bfb..000000000 --- a/kdefx/kimageeffect.h +++ /dev/null @@ -1,817 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1998, 1999, 2001, 2002 Daniel M. Duley <mosfet@interaccess.com> - (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> - (C) 1998, 1999 Dirk Mueller <mueller@kde.org> - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -// $Id$ - -#ifndef __KIMAGE_EFFECT_H -#define __KIMAGE_EFFECT_H - -#include <kdelibs_export.h> - -class TQImage; -class TQSize; -class TQColor; -class TQPoint; -class TQRect; - -/** - * This class includes various TQImage based graphical effects. - * - * Everything is - * static, so there is no need to create an instance of this class. You can - * just call the static methods. They are encapsulated here merely to provide - * a common namespace. - */ -class KDEFX_EXPORT KImageEffect -{ -public: - /** - * This enum provides a gradient type specification - * @see KImageEffect::blend(), KImageEffect::gradient(), - * KImageEffect::unbalancedGradient() - */ - enum GradientType { VerticalGradient, - HorizontalGradient, - DiagonalGradient, - CrossDiagonalGradient, - PyramidGradient, - RectangleGradient, - PipeCrossGradient, - EllipticGradient - }; - - /** - * This enum provides a RGB channel specification - * @see KImageEffect::blend(), KImageEffect::channelIntensity(), - * KImageEffect::modulate() - */ - enum RGBComponent { Red, //!< Red channel - Green, //!< Green channel - Blue, //!< Blue channel - Gray, //!< Grey channel - All //!< All channels - }; - - /** - * This enum provides a lighting direction specification - * @see KImageEffect::hash() - */ - enum Lighting {NorthLite, //!< Lighting from the top of the image - NWLite, //!< Lighting from the top left of the image - WestLite, //!< Lighting from the left of the image - SWLite, //!< Lighting from the bottom left of the image - SouthLite, //!< Lighting from the bottom of the image - SELite, //!< Lighting from the bottom right of the image - EastLite, //!< Lighting from the right of the image - NELite //!< Lighting from the top right of the image - }; - - /** - * This enum provides a modulation type specification - * @see KImageEffect::modulate() - */ - enum ModulationType { Intensity, //!< Modulate image intensity - Saturation, //!< Modulate image saturation - HueShift, //!< Modulate image hue - Contrast //!< Modulate image contrast - }; - - /** - * This enum provides a noise type specification - * @see KImageEffect::addNoise() - */ - enum NoiseType { UniformNoise=0, //!< Uniform distribution - GaussianNoise, //!< Gaussian distribution - MultiplicativeGaussianNoise, //!< Multiplicative Gaussian distribution - ImpulseNoise, //!< Impulse distribution - LaplacianNoise, //!< Laplacian distribution - PoissonNoise //!< Poisson distribution - }; - - /** - * This enum provides a rotation specification. - * @see KImageEffect::rotate() - */ - enum RotateDirection{ Rotate90, //!< Rotate 90 degrees to the right. - Rotate180, //!< Rotate 180 degrees. - Rotate270 //!< Rotate 90 degrees to the left. - }; - - /** - * This enum lists possible bumpmapping implementations. - * @see KImageEffect::bumpmap() - */ - enum BumpmapType { - Linear, - Spherical, - Sinuosidal - }; - - /** - * Create a gradient from color a to color b of the specified type. - * - * @param size The desired size of the gradient. - * @param ca Color a - * @param cb Color b - * @param type The type of gradient. - * @param ncols The number of colors to use when not running on a - * truecolor display. The gradient will be dithered to this number of - * colors. Pass 0 to prevent dithering. - */ - static TQImage gradient(const TQSize &size, const TQColor &ca, - const TQColor &cb, GradientType type, int ncols=3); - - /** - * Create an unbalanced gradient. - * - * An unbalanced gradient is a gradient where the transition from - * color a to color b is not linear, but in this case, exponential. - * - * @param size The desired size of the gradient. - * @param ca Color a - * @param cb Color b - * @param type The type of gradient. - * @param xfactor The x decay length. Use a value between -200 and 200. - * @param yfactor The y decay length. - * @param ncols The number of colors. See KImageEffect:gradient. - */ - static TQImage unbalancedGradient(const TQSize &size, const TQColor &ca, - const TQColor &cb, GradientType type, int xfactor = 100, - int yfactor = 100, int ncols = 3); - - /** - * Blends a color into the destination image, using an opacity - * value for blending one into another. Very fast direct pixel - * manipulation is used. - * - * This function uses MMX and SSE2 instructions to blend the - * image on processors that support it. - * - * @param clr source color to be blended into the destination image. - * @param dst destination image in which the source will be blended into. - * @param opacity opacity (between 0.0 and 1.0) which determines how much - * the source color will be blended into the destination image. - * @return The destination image (dst) containing the result. - * @author Karol Szwed (gallium@kde.org) - * @author Fredrik Höglund (fredrik@kde.org) - */ - static TQImage& blend(const TQColor& clr, TQImage& dst, float opacity); - - /** - * Blend the src image into the destination image, using an opacity - * value for blending one into another. Very fast direct pixel - * manipulation is used. - * - * This function uses MMX and SSE2 instructions to blend the - * images on processors that support it. - * - * @param src source image to be blended into the destination image. - * @param dst destination image in which the source will be blended into. - * @param opacity opacity (between 0.0 and 1.0) which determines how much - * the source image will be blended into the destination image. - * @return The destination image (dst) containing the result. - * @author Karol Szwed (gallium@kde.org) - * @author Fredrik Höglund (fredrik@kde.org) - */ - static TQImage& blend(TQImage& src, TQImage& dst, float opacity); - - /** - * Blend the provided image into a background of the indicated color. - * - * @param initial_intensity this parameter takes values from -1 to 1: - * a) if positive: how much to fade the image in its - * less affected spot - * b) if negative: roughly indicates how much of the image - * remains unaffected - * @param bgnd indicates the color of the background to blend in - * @param eff lets you choose what kind of blending you like - * @param anti_dir blend in the opposite direction (makes no much sense - * with concentric blending effects) - * @param image must be 32bpp - */ - static TQImage& blend(TQImage &image, float initial_intensity, - const TQColor &bgnd, GradientType eff, - bool anti_dir=false); - - /** - * Blend an image into another one, using a gradient type - * for blending from one to another. - * - * @param image1 source1 and result of blending - * @param image2 source2 of blending - * @param gt gradient type for blending between source1 and source2 - * @param xf x decay length for unbalanced gradient tpye - * @param yf y decay length for unbalanced gradient tpye - */ - static TQImage& blend(TQImage &image1,TQImage &image2, - GradientType gt, int xf=100, int yf=100); - - /** - * Blend an image into another one, using a color channel of a - * third image for the decision of blending from one to another. - * - * @param image1 Source 1 and result of blending - * @param image2 Source 2 of blending - * @param blendImage If the gray value of of pixel is 0, the result - * for this pixel is that of image1; for a gray value - * of 1, the pixel of image2 is used; for a value - * in between, a corresponding blending is used. - * @param channel The RBG channel to use for the blending decision. - */ - static TQImage& blend(TQImage &image1, TQImage &image2, - TQImage &blendImage, RGBComponent channel); - - /** - * Blend an image into another one, using alpha in the expected way. - * @param upper the "upper" image - * @param lower the "lower" image - * @param output the target image - * @author Rik Hemsley (rikkus) <rik@kde.org> - */ - static bool blend(const TQImage & upper, const TQImage & lower, TQImage & output); -// Not yet... static bool blend(const TQImage & image1, const TQImage & image2, TQImage & output, const TQRect & destRect); - - /** - * Blend an image into another one, using alpha in the expected way and - * over coordinates @p x and @p y with respect to the lower image. - * The output is a TQImage which is the @p upper image already blended - * with the @p lower one, so its size will be (in general) the same than - * @p upper instead of the same size than @p lower like the method above. - * In fact, the size of @p output is like upper's one only when it can be - * painted on lower, if there has to be some clipping, output's size will - * be the clipped area and x and y will be set to the correct up-left corner - * where the clipped rectangle begins. - * @param x x-coordinate of lower image - * @param y y-coordinate of lower image - * @param upper the "upper" image - * @param lower the "lower" image - * @param output the target image - */ - static bool blend(int &x, int &y, const TQImage & upper, const TQImage & lower, TQImage & output); - - /** - * Blend an image into another one, using alpha in the expected way and - * over coordinates @p x and @p y with respect to the lower image. - * The output is painted in the own @p lower image. This is an optimization - * of the blend method above provided by convenience. - * @param x x-coordinate of lower image - * @param y y-coordinate of lower image - * @param upper the "upper" image - * @param lower the "lower" image, which becomes the output image - */ - static bool blendOnLower(int x, int y, const TQImage & upper, const TQImage & lower); - - /** - * Blend part of an image into part of another, using the alpha channel in - * the expected way. - * Note that the destination rectangle will be correctly clipped. - * - * @param upper the "upper" image - * @param upperOffset Offset for the part of the upper image to be used. - * @param lower the "lower" image - * @param lowerRect Rectangle for the part of the lower image where the - * blending will occur. - * @since 3.2 - */ - static void blendOnLower(const TQImage &upper, const TQPoint &upperOffset, - TQImage &lower, const TQRect &lowerRect); - - /** - * Blend part of an image into part of another, using the opacity value - * and the alpha channel in the expected way. - * Note that the destination rectangle will be correctly clipped. - * - * @param upper the "upper" image - * @param upperOffset Offset for the part of the upper image to be used. - * @param lower the "lower" image - * @param lowerRect Rectangle for the part of the lower image where the - * blending will occur. - * @param opacity Opacity (between 0.0 and 1.0) which determines how much - * the source image will be blended into the destination image. - * @since 3.2 - */ - static void blendOnLower(const TQImage &upper, const TQPoint &upperOffset, - TQImage &lower, const TQRect &lowerRect, float opacity); - - /** - * Disposition of a source image on top of a destination image. - * @see KImageEffect::computeDestinationRect, KImageEffect::blendOnLower - * @since 3.2 - */ - enum Disposition { NoImage = 0, //!< Don't overlay - Centered, //!< Center top image on botton image - Tiled, //!< Tile top image on bottom image - CenterTiled, //!< Center and tile top image on bottom image - CenteredMaxpect, //!< Center and scale aspect - TiledMaxpect, //!< Tile and scale aspect - Scaled, //!< Scale - CenteredAutoFit //!< Center and scale or scale aspect - }; - - /** - * Compute the destination rectangle where to draw the upper image on top - * of another image using the given disposition. For tiled - * disposition, the rectangle should be duplicated on the whole area to - * obtained the wanted effect. - * - * @param lowerSize The size of the destination image. - * @param disposition The wanted disposition. - * @param upper The upper image. Note that this image may be scaled to - * adjust to the requested disposition. - * - * @return the computed rectangle. Its size may exceed @e lowerSize. - * @since 3.2 - */ - static TQRect computeDestinationRect(const TQSize &lowerSize, - Disposition disposition, TQImage &upper); - - /** - * Blend an image on top of another using a given disposition and a given - * opacity. The alpha channel of the upper image is used in the expected - * way. Beware the upper image may be modified. - * @since 3.2 - */ - static void blendOnLower(TQImage &upper, TQImage &lower, - Disposition disposition, float opacity); - - /** - * Modifies the intensity of a pixmap's RGB channel component. - * - * @param image The TQImage to process. - * @param percent Percent value. Use a negative value to dim. - * @param channel Which channel(s) should be modified - * @return The @p image, provided for convenience. - * @author Daniel M. Duley (mosfet) - */ - static TQImage& channelIntensity(TQImage &image, float percent, - RGBComponent channel); - - /** - * Fade an image to a certain background color. - * - * The number of colors will not be changed. - * - * @param image The TQImage to process. - * @param val The strength of the effect. 0 <= val <= 1. - * @param color The background color. - * @return Returns the image(), provided for convenience. - */ - static TQImage& fade(TQImage &image, float val, const TQColor &color); - - - /** - * This recolors a pixmap. The most dark color will become color a, - * the most bright one color b, and in between. - * - * @param image A TQImage to process. - * @param ca Color a - * @param cb Color b - * @param ncols The number of colors to dither the image to. - * Pass 0 to prevent dithering. - */ - static TQImage& flatten(TQImage &image, const TQColor &ca, - const TQColor &cb, int ncols=0); - - /** - * Build a hash on any given QImage - * - * @param image The TQImage to process - * @param lite The hash faces the indicated lighting (cardinal poles). - * @param spacing How many unmodified pixels in between hashes. - * @return Returns the image(), provided for convenience. - */ - static TQImage& hash(TQImage &image, Lighting lite=NorthLite, - unsigned int spacing=0); - - /** - * Either brighten or dim the image by a specified percent. - * For example, .50 will modify the colors by 50%. - * - * This function uses MMX instructions to process the image - * on processors that support it. - * - * @param image The TQImage to process. - * @param percent The percent value. Use a negative value to dim. - * @return Returns The image(), provided for convenience. - * @author Daniel M. Duley (mosfet) - * @author Benjamin Roe (ben@benroe.com) - */ - static TQImage& intensity(TQImage &image, float percent); - - /** - * Modulate the image with a color channel of another image. - * - * @param image The TQImage to modulate and result. - * @param modImage The TQImage to use for modulation. - * @param reverse Invert the meaning of image/modImage; result is image! - * @param type The modulation Type to use. - * @param factor The modulation amplitude; with 0 no effect [-200;200]. - * @param channel The RBG channel of image2 to use for modulation. - * @return Returns the image(), provided for convenience. - */ - static TQImage& modulate(TQImage &image, TQImage &modImage, bool reverse, - ModulationType type, int factor, RGBComponent channel); - - /** - * Convert an image to grayscale. - * - * @param image The TQImage to process. - * @param fast Set to @p true in order to use a faster but non-photographic - * quality algorithm. Appropriate for things such as toolbar icons. - * @return Returns the image(), provided for convenience. - * @author Daniel M. Duley (mosfet) - */ - static TQImage& toGray(TQImage &image, bool fast = false); - - /** - * Desaturate an image evenly. - * - * @param image The TQImage to process. - * @param desat A value between 0 and 1 setting the degree of desaturation - * @return Returns the image(), provided for convenience. - */ - static TQImage& desaturate(TQImage &image, float desat = 0.3); - - /** - * Fast, but low quality contrast of an image. Also see contrastHSV. - * - * @param image The TQImage to process. - * @param c A contrast value between -255 to 255. - * @return The image(), provided for convenience. - * @author Daniel M. Duley (mosfet) - * ### KDE 4: remove - */ - static TQImage& contrast(TQImage &image, int c); - - /** - * Dither an image using Floyd-Steinberg dithering for low-color - * situations. - * - * @param image The TQImage to process. - * @param palette The color palette to use - * @param size The size of the palette - * @return Returns the image(), provided for convenience. - */ - static TQImage& dither(TQImage &image, const TQColor *palette, int size); - - /** - * Calculate the image for a selected image, for instance a selected icon - * on the desktop. - * @param img the TQImage to select - * @param col the selected color, usually from TQColorGroup::highlight(). - */ - static TQImage& selectedImage( TQImage &img, const TQColor &col ); - - /** - * High quality, expensive HSV contrast. You can do a faster one by just - * taking a intensity threshold (ie: 128) and incrementing RGB color - * channels above it and decrementing those below it, but this gives much - * better results. - * - * @param img The TQImage to process. - * @param sharpen If true sharpness is increase, (spiffed). Otherwise - * it is decreased, (dulled). - * @author Daniel M. Duley (mosfet) - */ - static void contrastHSV(TQImage &img, bool sharpen=true); - - /** - * Normalises the pixel values to span the full range of color values. - * This is a contrast enhancement technique. - * @param img the image that is normalised - * @author Daniel M. Duley (mosfet) - */ - static void normalize(TQImage &img); - - /** - * Performs histogram equalisation on the reference - * image. - * @param img the image that is equalised - * @author Daniel M. Duley (mosfet) - */ - static void equalize(TQImage &img); - - /** - * Thresholds the reference image. You can also threshold images by using - * ThresholdDither in the various QPixmap/TQImage convert methods, but this - * lets you specify a threshold value. - * - * @param img The TQImage to process. - * @param value The threshold value. - * @author Daniel M. Duley (mosfet) - */ - static void threshold(TQImage &img, unsigned int value=128); - - /** - * Produces a 'solarization' effect seen when exposing a photographic - * film to light during the development process. - * - * @param img The TQImage to process. - * @param factor The extent of the solarization (0-99.9) - * @author Daniel M. Duley (mosfet) - */ - static void solarize(TQImage &img, double factor=50.0); - - /** - * Embosses the source image. This involves highlighting the edges - * and applying various other enhancements in order to get a metal - * effect. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @param sigma The standard deviation of the gaussian. Use 1 if you're not - * sure. - * @return The embossed image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage emboss(TQImage &src, double radius, double sigma); - - /** - * Convenience method. - */ - static TQImage emboss(TQImage &src); - - /** - * Minimizes speckle noise in the source image using the 8 hull - * algorithm. - * - * @param src The TQImage to process. - * @return The despeckled image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage despeckle(TQImage &src); - - /** - * Produces a neat little "charcoal" effect. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @param sigma The standard deviation of the gaussian. Use 1 if you're not - * sure. - * @return The charcoal image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage charcoal(TQImage &src, double radius, double sigma); - - /** - * This is provided for binary compatability only! Use the above method - * with a radius and sigma instead! - */ - static TQImage charcoal(TQImage &src, double factor=50.0); - - /** - * Rotates the image by the specified amount - * - * @param src The TQImage to process. - * @param r The rotate direction. - * @return The rotated image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage rotate(TQImage &src, RotateDirection r); - - /** - * Scales an image using simple pixel sampling. This does not produce - * nearly as nice a result as TQImage::smoothScale(), but has the - * advantage of being much faster - only a few milliseconds. - * - * @param src The TQImage to process. - * @param w The new width. - * @param h The new height. - * @return The scaled image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage sample(TQImage &src, int w, int h); - - /** - * Adds noise to an image. - * - * @param src The TQImage to process. - * @param type The algorithm used to generate the noise. - * @return The image with noise added. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage addNoise(TQImage &src, NoiseType type = GaussianNoise); - - /** - * Blurs an image by convolving pixel neighborhoods. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @param sigma The standard deviation of the gaussian. Use 1 if you're not - * sure. - * @return The blurred image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage blur(TQImage &src, double radius, double sigma); - - /** - * This is provided for binary compatability only! Use the above method - * with a radius and sigma instead! - */ - static TQImage blur(TQImage &src, double factor=50.0); - - /** - * Detects edges in an image using pixel neighborhoods and an edge - * detection mask. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @return The image with edges detected. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage edge(TQImage &src, double radius); - - /** - * Implodes an image by a specified percent. - * - * @param src The TQImage to process. - * @param factor The extent of the implosion. - * @param background An RGBA value to use for the background. After the - * effect some pixels may be "empty". This value is used for those pixels. - * @return The imploded image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage implode(TQImage &src, double factor=30.0, - unsigned int background = 0xFFFFFFFF); - - /** - * Produces an oil painting effect. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @return The new image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage oilPaintConvolve(TQImage &src, double radius); - - /** - * This is provided for binary compatability only! Use the above method - * instead! - */ - static TQImage oilPaint(TQImage &src, int radius=3); - - /** - * Sharpens the pixels in the image using pixel neighborhoods. - * - * @param src The TQImage to process. - * @param radius The radius of the gaussian not counting the - * center pixel. Use 0 and a suitable radius will be automatically used. - * @param sigma The standard deviation of the gaussian. Use 1 if you're not - * sure. - * @return The sharpened image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage sharpen(TQImage &src, double radius, double sigma); - - /** - * This is provided for binary compatability only! Use the above method - * instead! - */ - static TQImage sharpen(TQImage &src, double factor=30.0); - - /** - * Randomly displaces pixels. - * - * @param src The TQImage to process. - * @param amount The vicinity for choosing a random pixel to swap. - * @return The image with pixels displaced. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage spread(TQImage &src, unsigned int amount=3); - - /** - * Shades the image using a distance light source. - * - * @param src The TQImage to process. - * @param color_shading If true do color shading, otherwise do grayscale. - * @param azimuth Determines the light source and direction. - * @param elevation Determines the light source and direction. - * @return The shaded image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage shade(TQImage &src, bool color_shading=true, double azimuth=30.0, - double elevation=30.0); - /** - * Swirls the image by a specified amount - * - * @param src The TQImage to process. - * @param degrees The tightness of the swirl. - * @param background An RGBA value to use for the background. After the - * effect some pixels may be "empty". This value is used for those pixels. - * @return The swirled image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage swirl(TQImage &src, double degrees=50.0, unsigned int background = - 0xFFFFFFFF); - - /** - * Modifies the pixels along a sine wave. - * - * @param src The TQImage to process. - * @param amplitude The amplitude of the sine wave. - * @param frequency The frequency of the sine wave. - * @param background An RGBA value to use for the background. After the - * effect some pixels may be "empty". This value is used for those pixels. - * @return The new image. The original is not changed. - * @author Daniel M. Duley (mosfet) - */ - static TQImage wave(TQImage &src, double amplitude=25.0, double frequency=150.0, - unsigned int background = 0xFFFFFFFF); - - /** - * A bumpmapping algorithm. - * - * @param img the image you want bumpmap - * @param map the map used - * @param azimuth azimuth - * @param elevation elevation - * @param depth depth (not the depth of the image, but of the map) - * @param xofs X offset - * @param yofs Y offset - * @param waterlevel level that full transparency should represent - * @param ambient ambient lighting factor - * @param compensate compensate for darkening - * @param invert invert bumpmap - * @param type type of the bumpmap - * @param tiled tile the bumpmap over the image through the Y offset - * - * @return The destination image (dst) containing the result. - * @author Zack Rusin <zack@kde.org> - */ - static TQImage bumpmap(TQImage &img, TQImage &map, double azimuth, double elevation, - int depth, int xofs, int yofs, int waterlevel, - int ambient, bool compensate, bool invert, - BumpmapType type, bool tiled); - - /** - * Convert an image with standard alpha to premultiplied alpha - * - * @param img the image you want convert - * - * @return The destination image (dst) containing the result. - * @author Timothy Pearson <kb9vqf@pearsoncomputing.net> - */ - static TQImage convertToPremultipliedAlpha(TQImage input); - -private: - - /** - * Helper function to fast calc some altered (lighten, shaded) colors - * - */ - static unsigned int lHash(unsigned int c); - static unsigned int uHash(unsigned int c); - - /** - * Helper function to find the nearest color to the RBG triplet - */ - static int nearestColor( int r, int g, int b, const TQColor *pal, int size ); - - static void hull(const int x_offset, const int y_offset, const int polarity, - const int width, const int height, - unsigned int *f, unsigned int *g); - static unsigned int generateNoise(unsigned int pixel, NoiseType type); - static unsigned int interpolateColor(TQImage *image, double x, double y, - unsigned int background); - /* Various convolve routines */ - static int getOptimalKernelWidth(double radius, double sigma); - static bool convolveImage(TQImage *image, TQImage *dest, - const unsigned int order, - const double *kernel); - static void blurScanLine(double *kernel, int width, - unsigned int *src, unsigned int *dest, - int columns); - static int getBlurKernel(int width, double sigma, double **kernel); -}; - -#endif diff --git a/kdefx/kpixmap.cpp b/kdefx/kpixmap.cpp deleted file mode 100644 index 152ae6e83..000000000 --- a/kdefx/kpixmap.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 1998 Mark Donohoe <donohoe@kde.org> - * Stephan Kulow <coolo@kde.org> - * - * $Id$ - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include <tqpixmap.h> -#include <tqpainter.h> -#include <tqimage.h> -#include <tqbitmap.h> -#include <tqcolor.h> - -#include <stdlib.h> -#include "kpixmap.h" - -// Fast diffuse dither to 3x3x3 color cube -// Based on Qt's image conversion functions -static bool kdither_32_to_8( const TQImage *src, TQImage *dst ) -{ - // register QRgb *p; - uchar *b; - int y; - - if ( !dst->create(src->width(), src->height(), 8, 256) ) { - qWarning("KPixmap: destination image not valid\n"); - return false; - } - - dst->setNumColors( 256 ); - -#define MAX_R 2 -#define MAX_G 2 -#define MAX_B 2 -#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b)) - - int rc, gc, bc; - - for ( rc=0; rc<=MAX_R; rc++ ) // build 2x2x2 color cube - for ( gc=0; gc<=MAX_G; gc++ ) - for ( bc=0; bc<=MAX_B; bc++ ) { - dst->setColor( INDEXOF(rc,gc,bc), - tqRgb( rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B ) ); - } - - int sw = src->width(); - int* line1[3]; - int* line2[3]; - int* pv[3]; - - line1[0] = new int[src->width()]; - line2[0] = new int[src->width()]; - line1[1] = new int[src->width()]; - line2[1] = new int[src->width()]; - line1[2] = new int[src->width()]; - line2[2] = new int[src->width()]; - pv[0] = new int[sw]; - pv[1] = new int[sw]; - pv[2] = new int[sw]; - - for ( y=0; y < src->height(); y++ ) { - // p = (QRgb *)src->scanLine(y); - b = dst->scanLine(y); - int endian = (TQImage::systemBitOrder() == TQImage::BigEndian); - int x; - uchar* q = const_cast<TQImage*>(src)->scanLine(y); - uchar* q2 = const_cast<TQImage*>(src)->scanLine(y+1 < src->height() ? y + 1 : 0); - - for (int chan = 0; chan < 3; chan++) { - b = dst->scanLine(y); - int *l1 = (y&1) ? line2[chan] : line1[chan]; - int *l2 = (y&1) ? line1[chan] : line2[chan]; - if ( y == 0 ) { - for (int i=0; i<sw; i++) - l1[i] = q[i*4+chan+endian]; - } - if ( y+1 < src->height() ) { - for (int i=0; i<sw; i++) - l2[i] = q2[i*4+chan+endian]; - } - - // Bi-directional error diffusion - if ( y&1 ) { - for (x=0; x<sw; x++) { - int pix = QMAX(QMIN(2, (l1[x] * 2 + 128)/ 255), 0); - int err = l1[x] - pix * 255 / 2; - pv[chan][x] = pix; - - // Spread the error around... - if ( x+1<sw ) { - l1[x+1] += (err*7)>>4; - l2[x+1] += err>>4; - } - l2[x]+=(err*5)>>4; - if (x>1) - l2[x-1]+=(err*3)>>4; - } - } else { - for (x=sw; x-->0; ) { - int pix = QMAX(QMIN(2, (l1[x] * 2 + 128)/ 255), 0); - int err = l1[x] - pix * 255 / 2; - pv[chan][x] = pix; - - // Spread the error around... - if ( x > 0 ) { - l1[x-1] += (err*7)>>4; - l2[x-1] += err>>4; - } - l2[x]+=(err*5)>>4; - if (x+1 < sw) - l2[x+1]+=(err*3)>>4; - } - } - } - - if (!endian) { - for (x=0; x<sw; x++) - *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]); - } else { - for (x=0; x<sw; x++) - *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]); - } - - } - - delete [] line1[0]; - delete [] line2[0]; - delete [] line1[1]; - delete [] line2[1]; - delete [] line1[2]; - delete [] line2[2]; - delete [] pv[0]; - delete [] pv[1]; - delete [] pv[2]; - -#undef MAX_R -#undef MAX_G -#undef MAX_B -#undef INDEXOF - - return true; -} - -KPixmap::~KPixmap() -{ -} - -bool KPixmap::load( const TQString& fileName, const char *format, - int conversion_flags ) -{ - TQImageIO io( fileName, format ); - - bool result = io.read(); - - if ( result ) { - detach(); - result = convertFromImage( io.image(), conversion_flags ); - } - return result; -} - -bool KPixmap::load( const TQString& fileName, const char *format, - ColorMode mode ) -{ - int conversion_flags = 0; - switch (mode) { - case Color: - conversion_flags |= ColorOnly; - break; - case Mono: - conversion_flags |= MonoOnly; - break; - case LowColor: - conversion_flags |= LowOnly; - break; - case WebColor: - conversion_flags |= WebOnly; - break; - default: - break;// Nothing. - } - return load( fileName, format, conversion_flags ); -} - -bool KPixmap::convertFromImage( const TQImage &img, ColorMode mode ) -{ - int conversion_flags = 0; - switch (mode) { - case Color: - conversion_flags |= ColorOnly; - break; - case Mono: - conversion_flags |= MonoOnly; - break; - case LowColor: - conversion_flags |= LowOnly; - break; - case WebColor: - conversion_flags |= WebOnly; - break; - default: - break; // Nothing. - } - return convertFromImage( img, conversion_flags ); -} - -bool KPixmap::convertFromImage( const TQImage &img, int conversion_flags ) -{ - if ( img.isNull() ) { -#if defined(CHECK_NULL) - qWarning( "KPixmap::convertFromImage: Cannot convert a null image" ); -#endif - return false; - } - detach(); // detach other references - - int dd = defaultDepth(); - - // If color mode not one of KPixmaps extra modes nothing to do - if ( ( conversion_flags & KColorMode_Mask ) != LowOnly && - ( conversion_flags & KColorMode_Mask ) != WebOnly ) { - return TQPixmap::convertFromImage ( img, conversion_flags ); - } - - // If the default pixmap depth is not 8bpp, KPixmap color modes have no - // effect. Ignore them and use AutoColor instead. - if ( dd > 8 ) { - if ( ( conversion_flags & KColorMode_Mask ) == LowOnly || - ( conversion_flags & KColorMode_Mask ) == WebOnly ) - conversion_flags = (conversion_flags & ~KColorMode_Mask) | Auto; - return TQPixmap::convertFromImage ( img, conversion_flags ); - } - - if ( ( conversion_flags & KColorMode_Mask ) == LowOnly ) { - // Here we skimp a little on the possible conversion modes - // Don't offer ordered or threshold dither of RGB channels or - // diffuse or ordered dither of alpha channel. It hardly seems - // worth the effort for this specialized mode. - - // If image uses icon palette don't dither it. - if( img.numColors() > 0 && img.numColors() <=40 ) { - if ( checkColorTable( img ) ) - return TQPixmap::convertFromImage( img, TQPixmap::Auto ); - } - - TQBitmap mask; - bool isMask = false; - - TQImage image = img.convertDepth(32); - TQImage tImage( image.width(), image.height(), 8, 256 ); - - if( img.hasAlphaBuffer() ) { - image.setAlphaBuffer( true ); - tImage.setAlphaBuffer( true ); - isMask = mask.convertFromImage( img.createAlphaMask() ); - } - - kdither_32_to_8( &image, &tImage ); - - if( TQPixmap::convertFromImage( tImage ) ) { - if ( isMask ) TQPixmap::setMask( mask ); - return true; - } else - return false; - } else { - TQImage image = img.convertDepth( 32 ); - image.setAlphaBuffer( img.hasAlphaBuffer() ); - conversion_flags = (conversion_flags & ~ColorMode_Mask) | Auto; - return TQPixmap::convertFromImage ( image, conversion_flags ); - } -} - -static TQColor* kpixmap_iconPalette = 0; - -bool KPixmap::checkColorTable( const TQImage &image ) -{ - int i = 0; - - if (kpixmap_iconPalette == 0) { - kpixmap_iconPalette = new TQColor[40]; - - // Standard palette - kpixmap_iconPalette[i++] = red; - kpixmap_iconPalette[i++] = green; - kpixmap_iconPalette[i++] = blue; - kpixmap_iconPalette[i++] = cyan; - kpixmap_iconPalette[i++] = magenta; - kpixmap_iconPalette[i++] = yellow; - kpixmap_iconPalette[i++] = darkRed; - kpixmap_iconPalette[i++] = darkGreen; - kpixmap_iconPalette[i++] = darkBlue; - kpixmap_iconPalette[i++] = darkCyan; - kpixmap_iconPalette[i++] = darkMagenta; - kpixmap_iconPalette[i++] = darkYellow; - kpixmap_iconPalette[i++] = white; - kpixmap_iconPalette[i++] = lightGray; - kpixmap_iconPalette[i++] = gray; - kpixmap_iconPalette[i++] = darkGray; - kpixmap_iconPalette[i++] = black; - - // Pastels - kpixmap_iconPalette[i++] = TQColor( 255, 192, 192 ); - kpixmap_iconPalette[i++] = TQColor( 192, 255, 192 ); - kpixmap_iconPalette[i++] = TQColor( 192, 192, 255 ); - kpixmap_iconPalette[i++] = TQColor( 255, 255, 192 ); - kpixmap_iconPalette[i++] = TQColor( 255, 192, 255 ); - kpixmap_iconPalette[i++] = TQColor( 192, 255, 255 ); - - // Reds - kpixmap_iconPalette[i++] = TQColor( 64, 0, 0 ); - kpixmap_iconPalette[i++] = TQColor( 192, 0, 0 ); - - // Oranges - kpixmap_iconPalette[i++] = TQColor( 255, 128, 0 ); - kpixmap_iconPalette[i++] = TQColor( 192, 88, 0 ); - kpixmap_iconPalette[i++] = TQColor( 255, 168, 88 ); - kpixmap_iconPalette[i++] = TQColor( 255, 220, 168 ); - - // Blues - kpixmap_iconPalette[i++] = TQColor( 0, 0, 192 ); - - // Turquoise - kpixmap_iconPalette[i++] = TQColor( 0, 64, 64 ); - kpixmap_iconPalette[i++] = TQColor( 0, 192, 192 ); - - // Yellows - kpixmap_iconPalette[i++] = TQColor( 64, 64, 0 ); - kpixmap_iconPalette[i++] = TQColor( 192, 192, 0 ); - - // Greens - kpixmap_iconPalette[i++] = TQColor( 0, 64, 0 ); - kpixmap_iconPalette[i++] = TQColor( 0, 192, 0 ); - - // Purples - kpixmap_iconPalette[i++] = TQColor( 192, 0, 192 ); - - // Greys - kpixmap_iconPalette[i++] = TQColor( 88, 88, 88 ); - kpixmap_iconPalette[i++] = TQColor( 48, 48, 48 ); - kpixmap_iconPalette[i++] = TQColor( 220, 220, 220 ); - - } - - QRgb* ctable = image.tqcolorTable(); - - int ncols = image.numColors(); - int j; - - // Allow one failure which could be transparent background - int failures = 0; - - for ( i=0; i<ncols; i++ ) { - for ( j=0; j<40; j++ ) { - if ( kpixmap_iconPalette[j].red() == tqRed( ctable[i] ) && - kpixmap_iconPalette[j].green() == tqGreen( ctable[i] ) && - kpixmap_iconPalette[j].blue() == tqBlue( ctable[i] ) ) { - break; - } - } - - if ( j == 40 ) { - failures ++; - } - } - - return ( failures <= 1 ); - -} - -KPixmap::KPixmap(const TQPixmap& p) - : TQPixmap(p) -{ -} diff --git a/kdefx/kpixmap.h b/kdefx/kpixmap.h deleted file mode 100644 index 34397791e..000000000 --- a/kdefx/kpixmap.h +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is part of the KDE libraries - * Copyright (C) 1998 Mark Donohoe <donohoe@kde.org> - * Stephan Kulow <coolo@kde.org> - * - * $Id$ - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __KPIXMAP_H__ -#define __KPIXMAP_H__ - -#include <tqpixmap.h> - -#include <kdelibs_export.h> - -const int KColorMode_Mask = 0x00000300; -const int WebOnly = 0x00000200; -const int LowOnly = 0x00000300; - -class KPixmapPrivate; - -/** - * Off-screen paint device with extended features. - - * KPixmap has two new color modes, WebColor and LowColor, applicable - * to 8bpp displays. - - * In WebColor mode all images are dithered to the Netscape palette, - * even when they have their own color table. WebColor is the default - * mode for KPixmap so that standard applications can share the Netscape - * palette across the desktop. - - * In LowColor mode images are checked to see if their color table - * matches the KDE icon palette. If the color tables do not match, the - * images are dithered to a minimal 3x3x3 color cube. LowColor mode can - * be used to load icons, background images etc. so that components of - * the desktop which are always present use no more than 40 colors. - - * @author Mark Donohoe (donohoe@kde.org) - * @version $Id$ - */ -class KDEFX_EXPORT KPixmap : public TQPixmap -{ -public: - /** - * This enumeration provides a color pallete specification - * @see KPixmap::convertFromImage(), KPixmap::load() - */ - enum ColorMode { Auto, //!< Convert to monochrome if possible - Color, //!< Native display depth - Mono, //!< Monochrome pixmap - LowColor, //!< 3x3x3 color cube (or monochrome) - WebColor //!< Netscape pallete (or monochrome) - }; - /** - * This enumeration provides a gradient mode specification - */ - enum GradientMode { Horizontal, - Vertical, - Diagonal, - CrossDiagonal - }; - - /** - * Constructs a null pixmap. - */ - KPixmap() : TQPixmap() {}; - - /** - * Destructs the pixmap. - * ### KDE 4: remove - */ - ~KPixmap(); - - /** - * Copies the TQPixmap @p pix. - */ - KPixmap(const TQPixmap& pix); - - /** - * Converts an image and sets this pixmap. - * - * The conversion_flags argument is a bitwise-OR from the - * following choices. The options marked (default) are the - * choice if no other choice from the list is included (they - * are zero): - * - * Color/Mono preference - * - * @li WebColor - If the image has depth 1 and contains - * only black and white pixels then the pixmap becomes monochrome. If - * the pixmap has a depth of 8 bits per pixel then the Netscape - * palette is used for the pixmap color table. - * @li LowColor - If the image has depth 1 and contains only black and - * white pixels then the pixmap becomes monochrome. If the pixmap has a - * depth of 8 bits per pixel and the image does not posess a color table - * that matches the Icon palette a 3x3x3 color cube is used for the - * pixmap color table. - * @li AutoColor (default) - If the image has depth 1 and contains - * only black and white pixels, then the pixmap becomes - * monochrome. - * @li ColorOnly - The pixmap is dithered/converted to the native - * display depth. - * @li MonoOnly - The pixmap becomes monochrome. If necessary, it - * is dithered using the chosen dithering algorithm. - * - * Dithering mode preference, for RGB channels - * - * @li DiffuseDither (default) - A high quality dither. - * @li OrderedDither - A faster more ordered dither. - * @li ThresholdDither - No dithering, closest color is used. - * - * Dithering mode preference, for alpha channel - * - * @li DiffuseAlphaDither - A high quality dither. - * @li OrderedAlphaDither - A faster more ordered dither. - * @li ThresholdAlphaDither (default) - No dithering. - * - * Color matching versus dithering preference - * - * @li PreferDither - Always dither 32-bit images when the image - * is being converted to 8-bits. This is the default when - * converting to a pixmap. - * @li AvoidDither - Only dither 32-bit images if the image has - * more than 256 colors and it is being converted to 8-bits. - * This is the default when an image is converted for the - * purpose of saving to a file. - * - * Passing 0 for @p conversion_flags gives all the default - * options. - * - * @param img the image to convert - * @param conversion_flags bitmask, described above - * @return @p true if successful. - **/ - bool convertFromImage( const TQImage &img, int conversion_flags ); - - /** - * This is an overloaded member function, provided for - * convenience. It differs from the above function only in - * what argument(s) it accepts. - * @param img the image to convert - * @param mode a ColorMode to apply - * @return @p true if successful. - **/ - bool convertFromImage( const TQImage &img, ColorMode mode = WebColor ); - - /** - * Loads a pixmap from the file @p fileName. - * - * If format is specified, the loader attempts to read the - * pixmap using the specified format. If format is not - * specified (default), the loader reads a few bytes from the - * header to guess the file format. - * - * The TQImageIO documentation lists the supported image - * formats and explains how to add extra formats. - * - * @param fileName the name of the file to load the image from - * @param format the format for the image - * @param conversion_flags a bitmask, as described in - * convertFromImage() - * @return @p true if successful, or false if the pixmap - * could not be loaded. - **/ - bool load( const TQString& fileName, const char *format, - int conversion_flags ); - - /** - * This is an overloaded member function, provided for - * convenience. It differs from the above function only in - * what argument(s) it accepts. - * @param fileName the name of the file to load the image from - * @param format the format for the image - * @param mode a ColorMode to apply - * @return @p true if successful, or false if the pixmap - * could not be loaded. - **/ - bool load( const TQString& fileName, - const char *format = 0, - ColorMode mode = WebColor ); - - /** - * Returns true if the image posesses a color table that - * matches the Icon palette or false otherwise. - * - * An image with one color not found in the Icon palette is - * considered to be a match, since this extra color may be a - * transparent background. - * @param image the image to test - **/ - bool checkColorTable(const TQImage &image); - -private: - KPixmapPrivate *d; -}; - -#endif diff --git a/kdefx/kpixmapeffect.cpp b/kdefx/kpixmapeffect.cpp deleted file mode 100644 index c4bf04dae..000000000 --- a/kdefx/kpixmapeffect.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> - (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org> - (C) 1998, 1999 Dirk A. Mueller <mueller@kde.org> - -*/ - -// $Id$ - -#include <tqimage.h> -#include <tqpainter.h> - -#include "kpixmapeffect.h" -#include "kpixmap.h" -#include "kimageeffect.h" - -//====================================================================== -// -// Gradient effects -// -//====================================================================== - - -KPixmap& KPixmapEffect::gradient(KPixmap &pixmap, const TQColor &ca, - const TQColor &cb, GradientType eff, int ncols) -{ - if(pixmap.depth() > 8 && - (eff == VerticalGradient || eff == HorizontalGradient)) { - - int rDiff, gDiff, bDiff; - int rca, gca, bca /*, rcb, gcb, bcb*/; - - register int x, y; - - rDiff = (/*rcb = */ cb.red()) - (rca = ca.red()); - gDiff = (/*gcb = */ cb.green()) - (gca = ca.green()); - bDiff = (/*bcb = */ cb.blue()) - (bca = ca.blue()); - - register int rl = rca << 16; - register int gl = gca << 16; - register int bl = bca << 16; - - int rcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * rDiff; - int gcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * gDiff; - int bcdelta = ((1<<16) / (eff == VerticalGradient ? pixmap.height() : pixmap.width())) * bDiff; - - TQPainter p(&pixmap); - - // these for-loops could be merged, but the if's in the inner loop - // would make it slow - switch(eff) { - case VerticalGradient: - for ( y = 0; y < pixmap.height(); y++ ) { - rl += rcdelta; - gl += gcdelta; - bl += bcdelta; - - p.setPen(TQColor(rl>>16, gl>>16, bl>>16)); - p.drawLine(0, y, pixmap.width()-1, y); - } - break; - case HorizontalGradient: - for( x = 0; x < pixmap.width(); x++) { - rl += rcdelta; - gl += gcdelta; - bl += bcdelta; - - p.setPen(TQColor(rl>>16, gl>>16, bl>>16)); - p.drawLine(x, 0, x, pixmap.height()-1); - } - break; - default: - ; - } - } - else { - TQImage image = KImageEffect::gradient(pixmap.size(), ca, cb, - (KImageEffect::GradientType) eff, ncols); - pixmap.convertFromImage(image); - } - - return pixmap; -} - - -// ----------------------------------------------------------------------------- - -KPixmap& KPixmapEffect::unbalancedGradient(KPixmap &pixmap, const TQColor &ca, - const TQColor &cb, GradientType eff, int xfactor, int yfactor, - int ncols) -{ - TQImage image = KImageEffect::unbalancedGradient(pixmap.size(), ca, cb, - (KImageEffect::GradientType) eff, - xfactor, yfactor, ncols); - pixmap.convertFromImage(image); - - return pixmap; -} - - -//====================================================================== -// -// Intensity effects -// -//====================================================================== - - - -KPixmap& KPixmapEffect::intensity(KPixmap &pixmap, float percent) -{ - TQImage image = pixmap.convertToImage(); - KImageEffect::intensity(image, percent); - pixmap.convertFromImage(image); - - return pixmap; -} - - -// ----------------------------------------------------------------------------- - -KPixmap& KPixmapEffect::channelIntensity(KPixmap &pixmap, float percent, - RGBComponent channel) -{ - TQImage image = pixmap.convertToImage(); - KImageEffect::channelIntensity(image, percent, - (KImageEffect::RGBComponent) channel); - pixmap.convertFromImage(image); - - return pixmap; -} - - -//====================================================================== -// -// Blend effects -// -//====================================================================== - - -KPixmap& KPixmapEffect::blend(KPixmap &pixmap, float initial_intensity, - const TQColor &bgnd, GradientType eff, - bool anti_dir, int ncols) -{ - - TQImage image = pixmap.convertToImage(); - if (image.depth() <=8) - image = image.convertDepth(32); //Sloww.. - - KImageEffect::blend(image, initial_intensity, bgnd, - (KImageEffect::GradientType) eff, anti_dir); - - unsigned int tmp; - - if(pixmap.depth() <= 8 ) { - if ( ncols < 2 || ncols > 256 ) - ncols = 3; - TQColor *dPal = new TQColor[ncols]; - for (int i=0; i<ncols; i++) { - tmp = 0 + 255 * i / ( ncols - 1 ); - dPal[i].setRgb ( tmp, tmp, tmp ); - } - KImageEffect::dither(image, dPal, ncols); - pixmap.convertFromImage(image); - delete [] dPal; - } - else - pixmap.convertFromImage(image); - - return pixmap; -} - - -//====================================================================== -// -// Hash effects -// -//====================================================================== - -KPixmap& KPixmapEffect::hash(KPixmap &pixmap, Lighting lite, - unsigned int spacing, int ncols) -{ - TQImage image = pixmap.convertToImage(); - KImageEffect::hash(image, (KImageEffect::Lighting) lite, spacing); - - unsigned int tmp; - - if(pixmap.depth() <= 8 ) { - if ( ncols < 2 || ncols > 256 ) - ncols = 3; - TQColor *dPal = new TQColor[ncols]; - for (int i=0; i<ncols; i++) { - tmp = 0 + 255 * i / ( ncols - 1 ); - dPal[i].setRgb ( tmp, tmp, tmp ); - } - KImageEffect::dither(image, dPal, ncols); - pixmap.convertFromImage(image); - delete [] dPal; - } - else - pixmap.convertFromImage(image); - - return pixmap; -} - - -//====================================================================== -// -// Pattern effects -// -//====================================================================== - -#if 0 -void KPixmapEffect::pattern(KPixmap &pixmap, const TQColor &ca, - const TQColor &cb, unsigned pat[8]) -{ - TQImage img = pattern(pixmap.size(), ca, cb, pat); - pixmap.convertFromImage(img); -} -#endif - -// ----------------------------------------------------------------------------- - -KPixmap KPixmapEffect::pattern(const KPixmap& pmtile, TQSize size, - const TQColor &ca, const TQColor &cb, int ncols) -{ - if (pmtile.depth() > 8) - ncols = 0; - - TQImage img = pmtile.convertToImage(); - KImageEffect::flatten(img, ca, cb, ncols); - KPixmap pixmap; - pixmap.convertFromImage(img); - - return KPixmapEffect::createTiled(pixmap, size); -} - - -// ----------------------------------------------------------------------------- - -KPixmap KPixmapEffect::createTiled(const KPixmap& pixmap, TQSize size) -{ - KPixmap pix(size); - - TQPainter p(&pix); - p.drawTiledPixmap(0, 0, size.width(), size.height(), pixmap); - - return pix; -} - - -//====================================================================== -// -// Fade effects -// -//====================================================================== - -KPixmap& KPixmapEffect::fade(KPixmap &pixmap, double val, const TQColor &color) -{ - TQImage img = pixmap.convertToImage(); - KImageEffect::fade(img, val, color); - pixmap.convertFromImage(img); - - return pixmap; -} - - -// ----------------------------------------------------------------------------- -KPixmap& KPixmapEffect::toGray(KPixmap &pixmap, bool fast) -{ - TQImage img = pixmap.convertToImage(); - KImageEffect::toGray(img, fast); - pixmap.convertFromImage(img); - - return pixmap; -} - -// ----------------------------------------------------------------------------- -KPixmap& KPixmapEffect::desaturate(KPixmap &pixmap, float desat) -{ - TQImage img = pixmap.convertToImage(); - KImageEffect::desaturate(img, desat); - pixmap.convertFromImage(img); - - return pixmap; -} -// ----------------------------------------------------------------------------- -KPixmap& KPixmapEffect::contrast(KPixmap &pixmap, int c) -{ - TQImage img = pixmap.convertToImage(); - KImageEffect::contrast(img, c); - pixmap.convertFromImage(img); - - return pixmap; -} - -//====================================================================== -// -// Dither effects -// -//====================================================================== - -// ----------------------------------------------------------------------------- -KPixmap& KPixmapEffect::dither(KPixmap &pixmap, const TQColor *palette, int size) -{ - TQImage img = pixmap.convertToImage(); - KImageEffect::dither(img, palette, size); - pixmap.convertFromImage(img); - - return pixmap; -} - -//====================================================================== -// -// Other effects -// -//====================================================================== - -KPixmap KPixmapEffect::selectedPixmap( const KPixmap &pix, const TQColor &col ) -{ - TQImage img = pix.convertToImage(); - KImageEffect::selectedImage(img, col); - KPixmap outPix; - outPix.convertFromImage(img); - return outPix; -} diff --git a/kdefx/kpixmapeffect.h b/kdefx/kpixmapeffect.h deleted file mode 100644 index c0c8ac68c..000000000 --- a/kdefx/kpixmapeffect.h +++ /dev/null @@ -1,218 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 1998, 1999 Christian Tibirna <ctibirna@total.net> - (C) 1998, 1999 Daniel M. Duley <mosfet@kde.org> - (C) 1998, 1999 Dirk Mueller <mueller@kde.org> - -*/ - -// $Id$ - -#ifndef __KPIXMAP_EFFECT_H -#define __KPIXMAP_EFFECT_H - -#include <kdelibs_export.h> - -#include <tqsize.h> -class KPixmap; -class TQColor; - -/** - * This class includes various pixmap-based graphical effects. - * - * Everything is - * static, so there is no need to create an instance of this class. You can - * just call the static methods. They are encapsulated here merely to provide - * a common namespace. - */ -class KDEFX_EXPORT KPixmapEffect -{ -public: - enum GradientType { VerticalGradient, HorizontalGradient, - DiagonalGradient, CrossDiagonalGradient, - PyramidGradient, RectangleGradient, - PipeCrossGradient, EllipticGradient }; - enum RGBComponent { Red, Green, Blue }; - - enum Lighting {NorthLite, NWLite, WestLite, SWLite, - SouthLite, SELite, EastLite, NELite}; - - /** - * Creates a gradient from color a to color b of the specified type. - * - * @param pixmap The pixmap to process. - * @param ca Color a. - * @param cb Color b. - * @param type The type of gradient. - * @param ncols The number of colors to use when not running on a - * truecolor display. The gradient will be dithered to this number of - * colors. Pass 0 to prevent dithering. - * @return Returns the generated pixmap, for convenience. - */ - static KPixmap& gradient(KPixmap& pixmap, const TQColor &ca, const TQColor &cb, - GradientType type, int ncols=3); - - /** - * Creates an unbalanced gradient. - * - * An unbalanced gradient is a gradient where the transition from - * color a to color b is not linear, but in this case, exponential. - * - * @param pixmap The pixmap that should be written. - * @param ca Color a. - * @param cb Color b. - * @param type The type of gradient. - * @param xfactor The x decay length. Use a value between -200 and 200. - * @param yfactor The y decay length. - * @param ncols The number of colors. See #gradient. - * @return The generated pixmap, for convencience. - */ - static KPixmap& unbalancedGradient(KPixmap& pixmap, const TQColor &ca, - const TQColor &cb, GradientType type, int xfactor = 100, - int yfactor = 100, int ncols=3); - - /** - * Creates a pixmap of a given size with the given pixmap. - * - * if the - * given size is bigger than the size of the pixmap, the pixmap is - * tiled. - * - * @param pixmap This is the source pixmap - * @param size The size the new pixmap should have. - * @return The generated, tiled pixmap. - */ - static KPixmap createTiled(const KPixmap& pixmap, TQSize size); - - /** - * Either brightens or dims a pixmap by a specified ratio. - * - * @param pixmap The pixmap to process. - * @param ratio The ratio to use. Use negative value to dim. - * @return Returns The pixmap(), provided for convenience. - */ - static KPixmap& intensity(KPixmap& pixmap, float ratio); - - /** - * Modifies the intensity of a pixmap's RGB channel component. - * - * @param pixmap The pixmap to process. - * @param ratio value. Use negative value to dim. - * @param channel Which channel(s) should be modified - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& channelIntensity(KPixmap& pixmap, float ratio, - RGBComponent channel); - - /** - * Blends the provided pixmap into a background of the indicated color. - * - * @param pixmap The pixmap to process. - * @param initial_intensity this parameter takes values from -1 to 1: - * @li If positive, it tells how much to fade the image in its - * less affected spot. - * @li If negative, it tells roughly indicates how much of the image - * remains unaffected - * @param bgnd Indicates the color of the background to blend in. - * @param eff Lets you choose what kind of blending you like. - * @param anti_dir Blend in the opposite direction (makes no much sense - * with concentric blending effects). - * @param ncols The number of colors to dither the pixmap to. Only - * used for 8 bpp pixmaps. - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& blend(KPixmap& pixmap, float initial_intensity, - const TQColor &bgnd, GradientType eff, - bool anti_dir=false, int ncols=3); - - /** - * Builds a hash on any given pixmap. - * - * @param pixmap The pixmap to process. - * @param lite The hash faces the indicated lighting (cardinal poles) - * @param spacing How many unmodified pixels inbetween hashes. - * @param ncols The number of colors to dither the pixmap to. - * Only used for 8 bpp pixmaps. - * @return Returns The pixmap(), provided for convenience. - */ - static KPixmap& hash(KPixmap& pixmap, Lighting lite=NorthLite, - unsigned int spacing=0, int ncols=3); - - /** - * Creates a pattern from a pixmap. - * - * The given pixmap is "flattened" - * between color a to color b. - * Doesn't change the original pixmap. - * - * @param pixmap The pixmap to process. - * @param size The size of the returned pixmap. If @p size is larger than - * the original, the resulting pixmap will be tiled. - * @param ca Color a. - * @param cb Color b. - * @param ncols The number of colors to use. The image will be - * dithered to this depth. Pass zero to prevent dithering. - * @return The resulting pixmap. - */ - static KPixmap pattern(const KPixmap& pixmap, TQSize size, - const TQColor &ca, const TQColor &cb, int ncols=8); - - /** - * Fades a pixmap to a certain color. - * - * @param pixmap The pixmap to process. - * @param val The strength of the effect. 0 <= val <= 1. - * @param color The color to blend to. - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& fade(KPixmap& pixmap, double val, const TQColor &color); - - /** - * Converts a pixmap to grayscale. - * - * @param pixmap The pixmap to process. - * @param fast Set to @p true in order to use a faster but non-photographic - * quality algorithm. Appropriate for things such as toolbar icons. - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& toGray(KPixmap& pixmap, bool fast=false); - - /** - * Desaturates a pixmap. - * - * @param pixmap The pixmap to process. - * @param desat A value between 0 and 1 setting the degree of desaturation - * @return Returns The pixmap(), provided for convenience. - */ - static KPixmap& desaturate(KPixmap& pixmap, float desat = 0.3); - - /** - * Modifies the contrast of a pixmap. - * - * @param pixmap The pixmap to process. - * @param c A contrast value between -255 and 255. - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& contrast(KPixmap& pixmap, int c); - - /** - * Dithers a pixmap using Floyd-Steinberg dithering for low-color - * situations. - * - * @param pixmap The pixmap to process. - * @param palette The color palette to use. - * @param size The size of the palette. - * @return Returns the pixmap(), provided for convenience. - */ - static KPixmap& dither(KPixmap &pixmap, const TQColor *palette, int size); - - /** - * Calculate a 'selected' pixmap, for instance a selected icon - * on the desktop. - * @param pixmap the pixmap to select - * @param col the selected color, usually from TQColorGroup::highlight(). - */ - static KPixmap selectedPixmap( const KPixmap &pixmap, const TQColor &col ); -}; - - -#endif diff --git a/kdefx/kpixmapsplitter.cpp b/kdefx/kpixmapsplitter.cpp deleted file mode 100644 index 44b8f01fa..000000000 --- a/kdefx/kpixmapsplitter.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "kpixmapsplitter.h" - -KPixmapSplitter::KPixmapSplitter() - : m_itemSize( 4, 7 ), - m_vSpacing( 0 ), - m_hSpacing( 0 ), - m_numCols( 0 ), - m_numRows( 0 ), - m_dirty( false ) -{ -} - -KPixmapSplitter::~KPixmapSplitter() -{ -} - -void KPixmapSplitter::setPixmap( const TQPixmap& pixmap ) -{ - m_pixmap = pixmap; - m_dirty = true; -} - -void KPixmapSplitter::setItemSize( const TQSize& size ) -{ - if ( size != m_itemSize ) { - m_itemSize = size; - m_dirty = true; - } -} - -void KPixmapSplitter::setVSpacing( int spacing ) -{ - if ( spacing != m_vSpacing ) { - m_vSpacing = spacing; - m_dirty = true; - } -} - -void KPixmapSplitter::setHSpacing( int spacing ) -{ - if ( spacing != m_hSpacing ) { - m_hSpacing = spacing; - m_dirty = true; - } -} - - -TQRect KPixmapSplitter::coordinates( int pos ) -{ - if ( pos < 0 || m_pixmap.isNull() ) - return TQRect(); - - if ( m_dirty ) { - m_numCols = m_pixmap.width() / ( m_itemSize.width() + m_hSpacing ); - m_numRows = m_pixmap.height() / ( m_itemSize.height() + m_vSpacing ); - m_dirty = false; - // qDebug("cols: %i, rows: %i (pixmap: %i, %i)", m_numCols, m_numRows, m_pixmap.width(), m_pixmap.height()); - } - - if ( m_numCols == 0 || m_numRows == 0 ) - return TQRect(); - - int row = pos / m_numCols; - int col = pos - (row * m_numCols); - - return TQRect( col * (m_itemSize.width() + m_hSpacing), - row * (m_itemSize.height() + m_vSpacing), - m_itemSize.width(), - m_itemSize.height() ); -} - -TQRect KPixmapSplitter::coordinates( const TQChar& ch ) -{ - return coordinates( (unsigned char) ch.latin1() ); -} - diff --git a/kdefx/kpixmapsplitter.h b/kdefx/kpixmapsplitter.h deleted file mode 100644 index 84b5a8647..000000000 --- a/kdefx/kpixmapsplitter.h +++ /dev/null @@ -1,123 +0,0 @@ -/* This file is part of the KDE libraries - Copyright (C) 2000 Carsten Pfeiffer <pfeiffer@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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#ifndef KPIXMAPSPLITTER_H -#define KPIXMAPSPLITTER_H - -#include <tqpixmap.h> -#include <tqrect.h> -#include <tqsize.h> -#include <tqstring.h> - -#include <kdelibs_export.h> - -class KPixmapSplitterPrivate; -/** - * @short A class to split a pixmap into several items. - * - * If you have a pixmap containing several items (icons), you can use this - * class to get the coordinates of each item. - * - * For example, if you have a pixmap with 25 items and you want to get the - * 4th item as a pixmap (every item being 20x10 pixels): - * \code - * KPixmapSplitter splitter; - * splitter.setPixmap( somePixmap ); - * splitter.setItemSize( TQSize( 20, 10 )); - * - * TQPixmap item( 20, 10 ); - * item.fill( Qt::white ); - * TQRect rect = splitter.coordinates( 4 ); - * if ( !rect.isEmpty() ) - * bitBlt( &item, TQPoint(0,0), &somePixmap, rect, CopyROP ); - * \endcode - * - * @author Carsten Pfeiffer <pfeiffer@kde.org> - */ -class KDEFX_EXPORT KPixmapSplitter -{ -public: - /** - * Constructor, does nothing but initialize some default-values. - */ - KPixmapSplitter(); - ~KPixmapSplitter(); - - /** - * Sets the pixmap to be split. - */ - void setPixmap( const TQPixmap& pixmap ); - - /** - * @returns the pixmap that has been set via setPixmap(). - */ - const TQPixmap& pixmap() const { return m_pixmap; } - - /** - * Sets the size of the items you want to get out of the given pixmap. - * The TQRect of #coordinates(int) will have the width and height of exactly - * this @p size. - */ - void setItemSize( const TQSize& size ); - - /** - * @returns the set size of the items (coordinates) you want to get - * out of the given pixmap. - */ - TQSize itemSize() const { return m_itemSize; } - - /** - * If there is space between rows in the given pixmap, you have to specify - * how many pixels there are. - */ - void setVSpacing( int spacing ); - - /** - * If there is space between columns in the given pixmap, you have to - * specify how many pixels there are. - */ - void setHSpacing( int spacing ); - - /** - * @returns the coordinates of the item at position pos in the given - * pixmap. - */ - TQRect coordinates( int pos ); - - /** - * Overloaded for convenience. Returns the item at the position of the - * given character (when using a latin1 font-pixmap) - */ - TQRect coordinates( const TQChar& ch ); - -private: - TQPixmap m_pixmap; - TQSize m_itemSize; - - int m_vSpacing; - int m_hSpacing; - - int m_numCols; - int m_numRows; - - bool m_dirty; - KPixmapSplitterPrivate* d; -}; - -#endif // KPIXMAPSPLITTER_H diff --git a/kdefx/kstyle.cpp b/kdefx/kstyle.cpp deleted file mode 100644 index f80094fe4..000000000 --- a/kdefx/kstyle.cpp +++ /dev/null @@ -1,2370 +0,0 @@ -/* - * - * KStyle - * Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org> - * - * TQWindowsStyle CC_ListView and style images were kindly donated by TrollTech, - * Copyright (C) 1998-2000 TrollTech AS. - * - * Many thanks to Bradley T. Hughes for the 3 button scrollbar code. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "kstyle.h" - -#include <tqapplication.h> -#include <tqbitmap.h> -#include <tqmetaobject.h> -#include <tqcleanuphandler.h> -#include <tqmap.h> -#include <tqimage.h> -#include <tqlistview.h> -#include <tqmenubar.h> -#include <tqpainter.h> -#include <tqpixmap.h> -#include <tqpopupmenu.h> -#include <tqprogressbar.h> -#include <tqscrollbar.h> -#include <tqsettings.h> -#include <tqslider.h> -#include <tqstylefactory.h> -#include <tqtabbar.h> -#include <tqtoolbar.h> -#include <tqframe.h> - -#include <kpixmap.h> -#include <kpixmapeffect.h> -#include <kimageeffect.h> - -#ifdef Q_WS_X11 -# include <X11/Xlib.h> -# ifdef HAVE_XRENDER -# include <X11/extensions/Xrender.h> // schroder - extern bool qt_use_xrender; -# endif -#else -#undef HAVE_XRENDER -#endif - -#ifdef HAVE_XCOMPOSITE -#include <X11/extensions/Xrender.h> -#include <X11/extensions/Xcomposite.h> -#include <dlfcn.h> -#endif - -#include <limits.h> - -namespace -{ - // INTERNAL - enum TransparencyEngine { - Disabled = 0, - SoftwareTint, - SoftwareBlend, - XRender - }; - - // Drop Shadow - struct ShadowElements { - TQWidget* w1; - TQWidget* w2; - }; - typedef TQMap<const TQWidget*,ShadowElements> ShadowMap; - static ShadowMap *_shadowMap = 0; - TQSingleCleanupHandler<ShadowMap> cleanupShadowMap; - ShadowMap &shadowMap() { - if ( !_shadowMap ) { - _shadowMap = new ShadowMap; - cleanupShadowMap.set( &_shadowMap ); - } - return *_shadowMap; - } - - - // DO NOT ASK ME HOW I MADE THESE TABLES! - // (I probably won't remember anyway ;) - const double top_right_corner[16] = - { 0.949, 0.965, 0.980, 0.992, - 0.851, 0.890, 0.945, 0.980, - 0.706, 0.780, 0.890, 0.960, - 0.608, 0.706, 0.851, 0.949 }; - - const double bottom_right_corner[16] = - { 0.608, 0.706, 0.851, 0.949, - 0.706, 0.780, 0.890, 0.960, - 0.851, 0.890, 0.945, 0.980, - 0.949, 0.965, 0.980, 0.992 }; - - const double bottom_left_corner[16] = - { 0.949, 0.851, 0.706, 0.608, - 0.965, 0.890, 0.780, 0.706, - 0.980, 0.945, 0.890, 0.851, - 0.992, 0.980, 0.960, 0.949 }; - - const double shadow_strip[4] = - { 0.565, 0.675, 0.835, 0.945 }; - - static bool useDropShadow(TQWidget* w) - { - return w && w->tqmetaObject() && - w->tqmetaObject()->findProperty("KStyleMenuDropShadow") != -1; - } -} - -namespace -{ -class TransparencyHandler : public TQObject -{ - public: - TransparencyHandler(KStyle* style, TransparencyEngine tEngine, - float menuOpacity, bool useDropShadow); - ~TransparencyHandler(); - bool eventFilter(TQObject* object, TQEvent* event); - - protected: - void blendToColor(const TQColor &col); - void blendToPixmap(const TQColorGroup &cg, const TQWidget* p); -#ifdef HAVE_XRENDER - void XRenderBlendToPixmap(const TQWidget* p); -#endif - bool haveX11RGBASupport(); - TQImage handleRealAlpha(TQImage); - void createShadowWindows(const TQWidget* p); - void removeShadowWindows(const TQWidget* p); - void rightShadow(TQImage& dst); - void bottomShadow(TQImage& dst); - private: - bool dropShadow; - float opacity; - TQPixmap pix; - KStyle* kstyle; - TransparencyEngine te; -}; -} // namespace - -struct KStylePrivate -{ - bool highcolor : 1; - bool useFilledFrameWorkaround : 1; - bool etchDisabledText : 1; - bool scrollablePopupmenus : 1; - bool menuAltKeyNavigation : 1; - bool menuDropShadow : 1; - bool sloppySubMenus : 1; - bool semiTransparentRubberband : 1; - int popupMenuDelay; - float menuOpacity; - - TransparencyEngine transparencyEngine; - KStyle::KStyleScrollBarType scrollbarType; - TransparencyHandler* menuHandler; - KStyle::KStyleFlags flags; - - //For KPE_ListViewBranch - TQBitmap *verticalLine; - TQBitmap *horizontalLine; -}; - -// ----------------------------------------------------------------------------- - - -KStyle::KStyle( KStyleFlags flags, KStyleScrollBarType sbtype ) - : TQCommonStyle(), d(new KStylePrivate) -{ - d->flags = flags; - bool useMenuTransparency = (flags & AllowMenuTransparency); - d->useFilledFrameWorkaround = (flags & FilledFrameWorkaround); - d->scrollbarType = sbtype; - d->highcolor = TQPixmap::defaultDepth() > 8; - - // Read style settings - TQSettings settings; - d->popupMenuDelay = settings.readNumEntry ("/KStyle/Settings/PopupMenuDelay", 256); - d->sloppySubMenus = settings.readBoolEntry("/KStyle/Settings/SloppySubMenus", false); - d->etchDisabledText = settings.readBoolEntry("/KStyle/Settings/EtchDisabledText", true); - d->menuAltKeyNavigation = settings.readBoolEntry("/KStyle/Settings/MenuAltKeyNavigation", true); - d->scrollablePopupmenus = settings.readBoolEntry("/KStyle/Settings/ScrollablePopupMenus", false); - d->menuDropShadow = settings.readBoolEntry("/KStyle/Settings/MenuDropShadow", false); - d->semiTransparentRubberband = settings.readBoolEntry("/KStyle/Settings/SemiTransparentRubberband", false); - d->menuHandler = NULL; - - if (useMenuTransparency) { - TQString effectEngine = settings.readEntry("/KStyle/Settings/MenuTransparencyEngine", "Disabled"); - -#ifdef HAVE_XRENDER - if (effectEngine == "XRender") - d->transparencyEngine = XRender; -#else - if (effectEngine == "XRender") - d->transparencyEngine = SoftwareBlend; -#endif - else if (effectEngine == "SoftwareBlend") - d->transparencyEngine = SoftwareBlend; - else if (effectEngine == "SoftwareTint") - d->transparencyEngine = SoftwareTint; - else - d->transparencyEngine = Disabled; - - if (d->transparencyEngine != Disabled) { - // Create an instance of the menu transparency handler - d->menuOpacity = settings.readDoubleEntry("/KStyle/Settings/MenuOpacity", 0.90); - d->menuHandler = new TransparencyHandler(this, d->transparencyEngine, - d->menuOpacity, d->menuDropShadow); - } - } - - d->verticalLine = 0; - d->horizontalLine = 0; - - // Create a transparency handler if only drop shadows are enabled. - if (!d->menuHandler && d->menuDropShadow) - d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, d->menuDropShadow); -} - - -KStyle::~KStyle() -{ - delete d->verticalLine; - delete d->horizontalLine; - - delete d->menuHandler; - - d->menuHandler = NULL; - delete d; -} - - -TQString KStyle::defaultStyle() -{ - if (TQPixmap::defaultDepth() > 8) - return TQString("plastik"); - else - return TQString("light, 3rd revision"); -} - -void KStyle::polish( TQWidget* widget ) -{ - if ( d->useFilledFrameWorkaround ) - { - if ( TQFrame *frame = ::tqqt_cast< TQFrame* >( widget ) ) { - TQFrame::Shape tqshape = frame->frameShape(); - if (tqshape == TQFrame::ToolBarPanel || tqshape == TQFrame::MenuBarPanel) - widget->installEventFilter(this); - } - } - if (widget->isTopLevel()) - { - if (!d->menuHandler && useDropShadow(widget)) - d->menuHandler = new TransparencyHandler(this, Disabled, 1.0, false); - - if (d->menuHandler && useDropShadow(widget)) - widget->installEventFilter(d->menuHandler); - } -} - - -void KStyle::unPolish( TQWidget* widget ) -{ - if ( d->useFilledFrameWorkaround ) - { - if ( TQFrame *frame = ::tqqt_cast< TQFrame* >( widget ) ) { - TQFrame::Shape tqshape = frame->frameShape(); - if (tqshape == TQFrame::ToolBarPanel || tqshape == TQFrame::MenuBarPanel) - widget->removeEventFilter(this); - } - } - if (widget->isTopLevel() && d->menuHandler && useDropShadow(widget)) - widget->removeEventFilter(d->menuHandler); -} - - -// Style changes (should) always re-polish popups. -void KStyle::polishPopupMenu( TQPopupMenu* p ) -{ - if (!p->testWState( WState_Polished )) - p->setCheckable(true); - - // Install transparency handler if the effect is enabled. - if ( d->menuHandler && - (strcmp(p->name(), "tear off menu") != 0)) - p->installEventFilter(d->menuHandler); -} - - -// ----------------------------------------------------------------------------- -// KStyle extensions -// ----------------------------------------------------------------------------- - -void KStyle::setScrollBarType(KStyleScrollBarType sbtype) -{ - d->scrollbarType = sbtype; -} - -KStyle::KStyleFlags KStyle::styleFlags() const -{ - return d->flags; -} - -void KStyle::renderMenuBlendPixmap( KPixmap &pix, const TQColorGroup &cg, - const TQPopupMenu* /* popup */ ) const -{ - pix.fill(cg.button()); // Just tint as the default behavior -} - - -void KStyle::drawKStylePrimitive( KStylePrimitive kpe, - TQPainter* p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags, - const TQStyleOption& /* opt */ ) const -{ - switch( kpe ) - { - // Dock / Toolbar / General handles. - // --------------------------------- - - case KPE_DockWindowHandle: { - - // Draws a nice DockWindow handle including the dock title. - TQWidget* wid = const_cast<TQWidget*>(widget); - bool horizontal = flags & Style_Horizontal; - int x,y,w,h,x2,y2; - - r.rect( &x, &y, &w, &h ); - if ((w <= 2) || (h <= 2)) { - p->fillRect(r, cg.highlight()); - return; - } - - - x2 = x + w - 1; - y2 = y + h - 1; - - TQFont fnt; - fnt = TQApplication::font(wid); - fnt.setPointSize( fnt.pointSize()-2 ); - - // Draw the item on an off-screen pixmap - // to preserve Xft antialiasing for - // vertically oriented handles. - TQPixmap pix; - if (horizontal) - pix.resize( h-2, w-2 ); - else - pix.resize( w-2, h-2 ); - - TQString title = wid->parentWidget()->caption(); - TQPainter p2; - p2.begin(&pix); - p2.fillRect(pix.rect(), cg.brush(TQColorGroup::Highlight)); - p2.setPen(cg.highlightedText()); - p2.setFont(fnt); - p2.drawText(pix.rect(), AlignCenter, title); - p2.end(); - - // Draw a sunken bevel - p->setPen(cg.dark()); - p->drawLine(x, y, x2, y); - p->drawLine(x, y, x, y2); - p->setPen(cg.light()); - p->drawLine(x+1, y2, x2, y2); - p->drawLine(x2, y+1, x2, y2); - - if (horizontal) { - TQWMatrix m; - m.rotate(-90.0); - TQPixmap vpix = pix.xForm(m); - bitBlt(wid, r.x()+1, r.y()+1, &vpix); - } else - bitBlt(wid, r.x()+1, r.y()+1, &pix); - - break; - } - - - /* - * KPE_ListViewExpander and KPE_ListViewBranch are based on code from - * QWindowStyle's CC_ListView, kindly donated by TrollTech. - * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS. - */ - - case KPE_ListViewExpander: { - // Typical Windows style expand/collapse element. - int radius = (r.width() - 4) / 2; - int centerx = r.x() + r.width()/2; - int centery = r.y() + r.height()/2; - - // Outer box - p->setPen( cg.mid() ); - p->drawRect( r ); - - // plus or minus - p->setPen( cg.text() ); - p->drawLine( centerx - radius, centery, centerx + radius, centery ); - if ( flags & Style_On ) // Collapsed = On - p->drawLine( centerx, centery - radius, centerx, centery + radius ); - break; - } - - case KPE_ListViewBranch: { - // Typical Windows style listview branch element (dotted line). - - // Create the dotline pixmaps if not already created - if ( !d->verticalLine ) - { - // make 128*1 and 1*128 bitmaps that can be used for - // drawing the right sort of lines. - d->verticalLine = new TQBitmap( 1, 129, true ); - d->horizontalLine = new TQBitmap( 128, 1, true ); - TQPointArray a( 64 ); - TQPainter p2; - p2.begin( d->verticalLine ); - - int i; - for( i=0; i < 64; i++ ) - a.setPoint( i, 0, i*2+1 ); - p2.setPen( color1 ); - p2.drawPoints( a ); - p2.end(); - TQApplication::flushX(); - d->verticalLine->setMask( *d->verticalLine ); - - p2.begin( d->horizontalLine ); - for( i=0; i < 64; i++ ) - a.setPoint( i, i*2+1, 0 ); - p2.setPen( color1 ); - p2.drawPoints( a ); - p2.end(); - TQApplication::flushX(); - d->horizontalLine->setMask( *d->horizontalLine ); - } - - p->setPen( cg.text() ); // cg.dark() is bad for dark color schemes. - - if (flags & Style_Horizontal) - { - int point = r.x(); - int other = r.y(); - int end = r.x()+r.width(); - int thickness = r.height(); - - while( point < end ) - { - int i = 128; - if ( i+point > end ) - i = end-point; - p->drawPixmap( point, other, *d->horizontalLine, 0, 0, i, thickness ); - point += i; - } - - } else { - int point = r.y(); - int other = r.x(); - int end = r.y()+r.height(); - int thickness = r.width(); - int pixmapoffset = (flags & Style_NoChange) ? 0 : 1; // ### Hackish - - while( point < end ) - { - int i = 128; - if ( i+point > end ) - i = end-point; - p->drawPixmap( other, point, *d->verticalLine, 0, pixmapoffset, thickness, i ); - point += i; - } - } - - break; - } - - // Reimplement the other primitives in your styles. - // The current implementation just paints something visibly different. - case KPE_ToolBarHandle: - case KPE_GeneralHandle: - case KPE_SliderHandle: - p->fillRect(r, cg.light()); - break; - - case KPE_SliderGroove: - p->fillRect(r, cg.dark()); - break; - - default: - p->fillRect(r, Qt::yellow); // Something really bad happened - highlight. - break; - } -} - - -int KStyle::kPixelMetric( KStylePixelMetric kpm, const TQWidget* /* widget */) const -{ - int value; - switch(kpm) - { - case KPM_ListViewBranchThickness: - value = 1; - break; - - case KPM_MenuItemSeparatorHeight: - case KPM_MenuItemHMargin: - case KPM_MenuItemVMargin: - case KPM_MenuItemHFrame: - case KPM_MenuItemVFrame: - case KPM_MenuItemCheckMarkHMargin: - case KPM_MenuItemArrowHMargin: - case KPM_MenuItemTabSpacing: - default: - value = 0; - } - - return value; -} - -// ----------------------------------------------------------------------------- - -// #ifdef USE_QT4 // kdebindings / smoke needs this function declaration available at all times. Furthermore I don't think it would hurt to have the declaration available at all times...so leave these commented out for now - -//void KStyle::tqdrawPrimitive( TQ_ControlElement pe, -// TQPainter* p, -// const TQRect &r, -// const TQColorGroup &cg, -// SFlags flags, -// const TQStyleOption& opt ) const -//{ -// // FIXME: -// // What should "widget" be in actuality? How should I get it? From where? -// // Almost certainly it should not be null! -// TQWidget *widget = 0; -// tqdrawControl(pe, p, widget, r, cg, flags, opt); -//} - -// #endif // USE_QT4 - -// ----------------------------------------------------------------------------- - -void KStyle::tqdrawPrimitive( TQ_PrimitiveElement pe, - TQPainter* p, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags, - const TQStyleOption& opt ) const -{ - // TOOLBAR/DOCK WINDOW HANDLE - // ------------------------------------------------------------------------ - if (pe == PE_DockWindowHandle) - { - // Wild workarounds are here. Beware. - TQWidget *widget, *parent; - - if (p && p->device()->devType() == TQInternal::Widget) { - widget = static_cast<TQWidget*>(p->device()); - parent = widget->parentWidget(); - } else - return; // Don't paint on non-widgets - - // Check if we are a normal toolbar or a hidden dockwidget. - if ( parent && - (parent->inherits(TQTOOLBAR_OBJECT_NAME_STRING) || // Normal toolbar - (parent->inherits(TQMAINWINDOW_OBJECT_NAME_STRING)) )) // Collapsed dock - - // Draw a toolbar handle - drawKStylePrimitive( KPE_ToolBarHandle, p, widget, r, cg, flags, opt ); - - else if ( widget->inherits(TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING) ) - - // Draw a dock window handle - drawKStylePrimitive( KPE_DockWindowHandle, p, widget, r, cg, flags, opt ); - - else - // General handle, probably a kicker applet handle. - drawKStylePrimitive( KPE_GeneralHandle, p, widget, r, cg, flags, opt ); -#if QT_VERSION >= 0x030300 -#ifdef HAVE_XRENDER - } else if ( d->semiTransparentRubberband && pe == TQStyle::PE_RubberBand ) { - TQRect rect = r.normalize(); - TQPoint point; - point = p->xForm( point ); - - static XRenderColor clr = { 0, 0, 0, 0 }; - static unsigned long fillColor = 0; - if ( fillColor != cg.highlight().rgb() ) { - fillColor = cg.highlight().rgb(); - - unsigned long color = fillColor << 8 | 0x40; - - int red = (color >> 24) & 0xff; - int green = (color >> 16) & 0xff; - int blue = (color >> 8) & 0xff; - int alpha = (color >> 0) & 0xff; - - red = red * alpha / 255; - green = green * alpha / 255; - blue = blue * alpha / 255; - - clr.red = (red << 8) + red; - clr.green = (green << 8) + green; - clr.blue = (blue << 8) + blue; - clr.alpha = (alpha << 8) + alpha; - } - - XRenderFillRectangle( - p->tqdevice()->x11Display(), - PictOpOver, - p->tqdevice()->x11RenderHandle(), - &clr, - rect.x() + point.x(), - rect.y() + point.y(), - rect.width(), - rect.height() ); - - p->save(); - p->setRasterOp( TQt::CopyROP ); - p->setPen( TQPen( cg.highlight().dark( 160 ), 1 ) ); - p->setBrush( NoBrush ); - p->drawRect( - rect.x() + point.x(), - rect.y() + point.y(), - rect.width(), - rect.height() ); - p->restore(); -#endif -#endif - } else - TQCommonStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt ); -} - - - -void KStyle::tqdrawControl( TQ_ControlElement element, - TQPainter* p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags, - const TQStyleOption &opt ) const -{ - switch (element) - { - // TABS - // ------------------------------------------------------------------------ - case CE_TabBarTab: { - const TQTabBar* tb = (const TQTabBar*) widget; - TQTabBar::Shape tbs = tb->tqshape(); - bool selected = flags & Style_Selected; - int x = r.x(), y=r.y(), bottom=r.bottom(), right=r.right(); - - switch (tbs) { - - case TQTabBar::RoundedAbove: { - if (!selected) - p->translate(0,1); - p->setPen(selected ? cg.light() : cg.shadow()); - p->drawLine(x, y+4, x, bottom); - p->drawLine(x, y+4, x+4, y); - p->drawLine(x+4, y, right-1, y); - if (selected) - p->setPen(cg.shadow()); - p->drawLine(right, y+1, right, bottom); - - p->setPen(cg.midlight()); - p->drawLine(x+1, y+4, x+1, bottom); - p->drawLine(x+1, y+4, x+4, y+1); - p->drawLine(x+5, y+1, right-2, y+1); - - if (selected) { - p->setPen(cg.mid()); - p->drawLine(right-1, y+1, right-1, bottom); - } else { - p->setPen(cg.mid()); - p->drawPoint(right-1, y+1); - p->drawLine(x+4, y+2, right-1, y+2); - p->drawLine(x+3, y+3, right-1, y+3); - p->fillRect(x+2, y+4, r.width()-3, r.height()-6, cg.mid()); - - p->setPen(cg.light()); - p->drawLine(x, bottom-1, right, bottom-1); - p->translate(0,-1); - } - break; - } - - case TQTabBar::RoundedBelow: { - if (!selected) - p->translate(0,-1); - p->setPen(selected ? cg.light() : cg.shadow()); - p->drawLine(x, bottom-4, x, y); - if (selected) - p->setPen(cg.mid()); - p->drawLine(x, bottom-4, x+4, bottom); - if (selected) - p->setPen(cg.shadow()); - p->drawLine(x+4, bottom, right-1, bottom); - p->drawLine(right, bottom-1, right, y); - - p->setPen(cg.midlight()); - p->drawLine(x+1, bottom-4, x+1, y); - p->drawLine(x+1, bottom-4, x+4, bottom-1); - p->drawLine(x+5, bottom-1, right-2, bottom-1); - - if (selected) { - p->setPen(cg.mid()); - p->drawLine(right-1, y, right-1, bottom-1); - } else { - p->setPen(cg.mid()); - p->drawPoint(right-1, bottom-1); - p->drawLine(x+4, bottom-2, right-1, bottom-2); - p->drawLine(x+3, bottom-3, right-1, bottom-3); - p->fillRect(x+2, y+2, r.width()-3, r.height()-6, cg.mid()); - p->translate(0,1); - p->setPen(cg.dark()); - p->drawLine(x, y, right, y); - } - break; - } - - case TQTabBar::TriangularAbove: { - if (!selected) - p->translate(0,1); - p->setPen(selected ? cg.light() : cg.shadow()); - p->drawLine(x, bottom, x, y+6); - p->drawLine(x, y+6, x+6, y); - p->drawLine(x+6, y, right-6, y); - if (selected) - p->setPen(cg.mid()); - p->drawLine(right-5, y+1, right-1, y+5); - p->setPen(cg.shadow()); - p->drawLine(right, y+6, right, bottom); - - p->setPen(cg.midlight()); - p->drawLine(x+1, bottom, x+1, y+6); - p->drawLine(x+1, y+6, x+6, y+1); - p->drawLine(x+6, y+1, right-6, y+1); - p->drawLine(right-5, y+2, right-2, y+5); - p->setPen(cg.mid()); - p->drawLine(right-1, y+6, right-1, bottom); - - TQPointArray a(6); - a.setPoint(0, x+2, bottom); - a.setPoint(1, x+2, y+7); - a.setPoint(2, x+7, y+2); - a.setPoint(3, right-7, y+2); - a.setPoint(4, right-2, y+7); - a.setPoint(5, right-2, bottom); - p->setPen (selected ? cg.background() : cg.mid()); - p->setBrush(selected ? cg.background() : cg.mid()); - p->drawPolygon(a); - p->setBrush(NoBrush); - if (!selected) { - p->translate(0,-1); - p->setPen(cg.light()); - p->drawLine(x, bottom, right, bottom); - } - break; - } - - default: { // TQTabBar::TriangularBelow - if (!selected) - p->translate(0,-1); - p->setPen(selected ? cg.light() : cg.shadow()); - p->drawLine(x, y, x, bottom-6); - if (selected) - p->setPen(cg.mid()); - p->drawLine(x, bottom-6, x+6, bottom); - if (selected) - p->setPen(cg.shadow()); - p->drawLine(x+6, bottom, right-6, bottom); - p->drawLine(right-5, bottom-1, right-1, bottom-5); - if (!selected) - p->setPen(cg.shadow()); - p->drawLine(right, bottom-6, right, y); - - p->setPen(cg.midlight()); - p->drawLine(x+1, y, x+1, bottom-6); - p->drawLine(x+1, bottom-6, x+6, bottom-1); - p->drawLine(x+6, bottom-1, right-6, bottom-1); - p->drawLine(right-5, bottom-2, right-2, bottom-5); - p->setPen(cg.mid()); - p->drawLine(right-1, bottom-6, right-1, y); - - TQPointArray a(6); - a.setPoint(0, x+2, y); - a.setPoint(1, x+2, bottom-7); - a.setPoint(2, x+7, bottom-2); - a.setPoint(3, right-7, bottom-2); - a.setPoint(4, right-2, bottom-7); - a.setPoint(5, right-2, y); - p->setPen (selected ? cg.background() : cg.mid()); - p->setBrush(selected ? cg.background() : cg.mid()); - p->drawPolygon(a); - p->setBrush(NoBrush); - if (!selected) { - p->translate(0,1); - p->setPen(cg.dark()); - p->drawLine(x, y, right, y); - } - break; - } - }; - - break; - } - - // Popup menu scroller - // ------------------------------------------------------------------------ - case CE_PopupMenuScroller: { - p->fillRect(r, cg.background()); - tqdrawPrimitive(PE_ButtonTool, p, r, cg, Style_Enabled); - tqdrawPrimitive((flags & Style_Up) ? PE_ArrowUp : PE_ArrowDown, p, r, cg, Style_Enabled); - break; - } - - - // PROGRESSBAR - // ------------------------------------------------------------------------ - case CE_ProgressBarGroove: { - TQRect fr = subRect(SR_ProgressBarGroove, widget); - tqdrawPrimitive(PE_Panel, p, fr, cg, Style_Sunken, TQStyleOption::SO_Default); - break; - } - - case CE_ProgressBarContents: { - // ### Take into account totalSteps() for busy indicator - const TQProgressBar* pb = (const TQProgressBar*)widget; - TQRect cr = subRect(SR_ProgressBarContents, widget); - double progress = pb->progress(); - bool reverse = TQApplication::reverseLayout(); - int steps = pb->totalSteps(); - - if (!cr.isValid()) - return; - - // Draw progress bar - if (progress > 0 || steps == 0) { - double pg = (steps == 0) ? 0.1 : progress / steps; - int width = QMIN(cr.width(), (int)(pg * cr.width())); - if (steps == 0) { //Busy indicator - - if (width < 1) width = 1; //A busy indicator with width 0 is kind of useless - - int remWidth = cr.width() - width; //Never disappear completely - if (remWidth <= 0) remWidth = 1; //Do something non-crashy when too small... - - int pstep = int(progress) % ( 2 * remWidth ); - - if ( pstep > remWidth ) { - //Bounce about.. We're remWidth + some delta, we want to be remWidth - delta... - // - ( (remWidth + some delta) - 2* remWidth ) = - (some deleta - remWidth) = remWidth - some delta.. - pstep = - (pstep - 2 * remWidth ); - } - - if (reverse) - p->fillRect(cr.x() + cr.width() - width - pstep, cr.y(), width, cr.height(), - cg.brush(TQColorGroup::Highlight)); - else - p->fillRect(cr.x() + pstep, cr.y(), width, cr.height(), - cg.brush(TQColorGroup::Highlight)); - - return; - } - - - // Do fancy gradient for highcolor displays - if (d->highcolor) { - TQColor c(cg.highlight()); - KPixmap pix; - pix.resize(cr.width(), cr.height()); - KPixmapEffect::gradient(pix, reverse ? c.light(150) : c.dark(150), - reverse ? c.dark(150) : c.light(150), - KPixmapEffect::HorizontalGradient); - if (reverse) - p->drawPixmap(cr.x()+(cr.width()-width), cr.y(), pix, - cr.width()-width, 0, width, cr.height()); - else - p->drawPixmap(cr.x(), cr.y(), pix, 0, 0, width, cr.height()); - } else - if (reverse) - p->fillRect(cr.x()+(cr.width()-width), cr.y(), width, cr.height(), - cg.brush(TQColorGroup::Highlight)); - else - p->fillRect(cr.x(), cr.y(), width, cr.height(), - cg.brush(TQColorGroup::Highlight)); - } - break; - } - - case CE_ProgressBarLabel: { - const TQProgressBar* pb = (const TQProgressBar*)widget; - TQRect cr = subRect(SR_ProgressBarContents, widget); - double progress = pb->progress(); - bool reverse = TQApplication::reverseLayout(); - int steps = pb->totalSteps(); - - if (!cr.isValid()) - return; - - TQFont font = p->font(); - font.setBold(true); - p->setFont(font); - - // Draw label - if (progress > 0 || steps == 0) { - double pg = (steps == 0) ? 1.0 : progress / steps; - int width = QMIN(cr.width(), (int)(pg * cr.width())); - TQRect crect; - if (reverse) - crect.setRect(cr.x()+(cr.width()-width), cr.y(), cr.width(), cr.height()); - else - crect.setRect(cr.x()+width, cr.y(), cr.width(), cr.height()); - - p->save(); - p->setPen(pb->isEnabled() ? (reverse ? cg.text() : cg.highlightedText()) : cg.text()); - p->drawText(r, AlignCenter, pb->progressString()); - p->setClipRect(crect); - p->setPen(reverse ? cg.highlightedText() : cg.text()); - p->drawText(r, AlignCenter, pb->progressString()); - p->restore(); - - } else { - p->setPen(cg.text()); - p->drawText(r, AlignCenter, pb->progressString()); - } - - break; - } - - default: - TQCommonStyle::tqdrawControl(element, p, widget, r, cg, flags, opt); - } -} - - -TQRect KStyle::subRect(SubRect r, const TQWidget* widget) const -{ - switch(r) - { - // KDE2 look smooth progress bar - // ------------------------------------------------------------------------ - case SR_ProgressBarGroove: - return widget->rect(); - - case SR_ProgressBarContents: - case SR_ProgressBarLabel: { - // ### take into account indicatorFollowsStyle() - TQRect rt = widget->rect(); - return TQRect(rt.x()+2, rt.y()+2, rt.width()-4, rt.height()-4); - } - - default: - return TQCommonStyle::subRect(r, widget); - } -} - - -int KStyle::tqpixelMetric(PixelMetric m, const TQWidget* widget) const -{ - switch(m) - { - // BUTTONS - // ------------------------------------------------------------------------ - case PM_ButtonShiftHorizontal: // Offset by 1 - case PM_ButtonShiftVertical: // ### Make configurable - return 1; - - case PM_DockWindowHandleExtent: - { - TQWidget* parent = 0; - // Check that we are not a normal toolbar or a hidden dockwidget, - // in which case we need to adjust the height for font size - if (widget && (parent = widget->parentWidget() ) - && !parent->inherits(TQTOOLBAR_OBJECT_NAME_STRING) - && !parent->inherits(TQMAINWINDOW_OBJECT_NAME_STRING) - && widget->inherits(TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING) ) - return widget->fontMetrics().lineSpacing(); - else - return TQCommonStyle::tqpixelMetric(m, widget); - } - - // TABS - // ------------------------------------------------------------------------ - case PM_TabBarTabHSpace: - return 24; - - case PM_TabBarTabVSpace: { - const TQTabBar * tb = (const TQTabBar *) widget; - if ( tb->tqshape() == TQTabBar::RoundedAbove || - tb->tqshape() == TQTabBar::RoundedBelow ) - return 10; - else - return 4; - } - - case PM_TabBarTabOverlap: { - const TQTabBar* tb = (const TQTabBar*)widget; - TQTabBar::Shape tbs = tb->tqshape(); - - if ( (tbs == TQTabBar::RoundedAbove) || - (tbs == TQTabBar::RoundedBelow) ) - return 0; - else - return 2; - } - - // SLIDER - // ------------------------------------------------------------------------ - case PM_SliderLength: - return 18; - - case PM_SliderThickness: - return 24; - - // Determines how much space to leave for the actual non-tickmark - // portion of the slider. - case PM_SliderControlThickness: { - const TQSlider* slider = (const TQSlider*)widget; - TQSlider::TickSetting ts = slider->tickmarks(); - int thickness = (slider->orientation() == Qt::Horizontal) ? - slider->height() : slider->width(); - switch (ts) { - case TQSlider::NoMarks: // Use total area. - break; - case TQSlider::Both: - thickness = (thickness/2) + 3; // Use approx. 1/2 of area. - break; - default: // Use approx. 2/3 of area - thickness = ((thickness*2)/3) + 3; - break; - }; - return thickness; - } - - // SPLITTER - // ------------------------------------------------------------------------ - case PM_SplitterWidth: - if (widget && widget->inherits("QDockWindowResizeHandle")) - return 8; // ### why do we need 2pix extra? - else - return 6; - - // FRAMES - // ------------------------------------------------------------------------ - case PM_MenuBarFrameWidth: - return 1; - - case PM_DockWindowFrameWidth: - return 1; - - // GENERAL - // ------------------------------------------------------------------------ - case PM_MaximumDragDistance: - return -1; - - case PM_MenuBarItemSpacing: - return 5; - - case PM_ToolBarItemSpacing: - return 0; - - case PM_PopupMenuScrollerHeight: - return tqpixelMetric( PM_ScrollBarExtent, 0); - - default: - return TQCommonStyle::tqpixelMetric( m, widget ); - } -} - -//Helper to find the next sibling that's not hidden -static TQListViewItem* nextVisibleSibling(TQListViewItem* item) -{ - TQListViewItem* sibling = item; - do - { - sibling = sibling->nextSibling(); - } - while (sibling && !sibling->isVisible()); - - return sibling; -} - -void KStyle::tqdrawComplexControl( TQ_ComplexControl control, - TQPainter* p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags, - SCFlags controls, - SCFlags active, - const TQStyleOption &opt ) const -{ - switch(control) - { - // 3 BUTTON SCROLLBAR - // ------------------------------------------------------------------------ - case CC_ScrollBar: { - // Many thanks to Brad Hughes for contributing this code. - bool useThreeButtonScrollBar = (d->scrollbarType & ThreeButtonScrollBar); - - const TQScrollBar *sb = (const TQScrollBar*)widget; - bool maxedOut = (sb->minValue() == sb->maxValue()); - bool horizontal = (sb->orientation() == Qt::Horizontal); - SFlags sflags = ((horizontal ? Style_Horizontal : Style_Default) | - (maxedOut ? Style_Default : Style_Enabled)); - - TQRect addline, subline, subline2, addpage, subpage, slider, first, last; - subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt); - addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt); - subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt); - addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt); - slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt); - first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt); - last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt); - subline2 = addline; - - if ( useThreeButtonScrollBar ) - if (horizontal) - subline2.moveBy(-addline.width(), 0); - else - subline2.moveBy(0, -addline.height()); - - // Draw the up/left button set - if ((controls & SC_ScrollBarSubLine) && subline.isValid()) { - tqdrawPrimitive(PE_ScrollBarSubLine, p, subline, cg, - sflags | (active == SC_ScrollBarSubLine ? - Style_Down : Style_Default)); - - if (useThreeButtonScrollBar && subline2.isValid()) - tqdrawPrimitive(PE_ScrollBarSubLine, p, subline2, cg, - sflags | (active == SC_ScrollBarSubLine ? - Style_Down : Style_Default)); - } - - if ((controls & SC_ScrollBarAddLine) && addline.isValid()) - tqdrawPrimitive(PE_ScrollBarAddLine, p, addline, cg, - sflags | ((active == SC_ScrollBarAddLine) ? - Style_Down : Style_Default)); - - if ((controls & SC_ScrollBarSubPage) && subpage.isValid()) - tqdrawPrimitive(PE_ScrollBarSubPage, p, subpage, cg, - sflags | ((active == SC_ScrollBarSubPage) ? - Style_Down : Style_Default)); - - if ((controls & SC_ScrollBarAddPage) && addpage.isValid()) - tqdrawPrimitive(PE_ScrollBarAddPage, p, addpage, cg, - sflags | ((active == SC_ScrollBarAddPage) ? - Style_Down : Style_Default)); - - if ((controls & SC_ScrollBarFirst) && first.isValid()) - tqdrawPrimitive(PE_ScrollBarFirst, p, first, cg, - sflags | ((active == SC_ScrollBarFirst) ? - Style_Down : Style_Default)); - - if ((controls & SC_ScrollBarLast) && last.isValid()) - tqdrawPrimitive(PE_ScrollBarLast, p, last, cg, - sflags | ((active == SC_ScrollBarLast) ? - Style_Down : Style_Default)); - - if ((controls & SC_ScrollBarSlider) && slider.isValid()) { - tqdrawPrimitive(PE_ScrollBarSlider, p, slider, cg, - sflags | ((active == SC_ScrollBarSlider) ? - Style_Down : Style_Default)); - // Draw focus rect - if (sb->hasFocus()) { - TQRect fr(slider.x() + 2, slider.y() + 2, - slider.width() - 5, slider.height() - 5); - tqdrawPrimitive(PE_FocusRect, p, fr, cg, Style_Default); - } - } - break; - } - - - // SLIDER - // ------------------------------------------------------------------- - case CC_Slider: { - const TQSlider* slider = (const TQSlider*)widget; - TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove, opt); - TQRect handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle, opt); - - // Double-buffer slider for no flicker - TQPixmap pix(widget->size()); - TQPainter p2; - p2.begin(&pix); - - if ( slider->parentWidget() && - slider->parentWidget()->backgroundPixmap() && - !slider->parentWidget()->backgroundPixmap()->isNull() ) { - TQPixmap pixmap = *(slider->parentWidget()->backgroundPixmap()); - p2.drawTiledPixmap(r, pixmap, slider->pos()); - } else - pix.fill(cg.background()); - - // Draw slider groove - if ((controls & SC_SliderGroove) && groove.isValid()) { - drawKStylePrimitive( KPE_SliderGroove, &p2, widget, groove, cg, flags, opt ); - - // Draw the focus rect around the groove - if (slider->hasFocus()) - tqdrawPrimitive(PE_FocusRect, &p2, groove, cg); - } - - // Draw the tickmarks - if (controls & SC_SliderTickmarks) - TQCommonStyle::tqdrawComplexControl(control, &p2, widget, - r, cg, flags, SC_SliderTickmarks, active, opt); - - // Draw the slider handle - if ((controls & SC_SliderHandle) && handle.isValid()) { - if (active == SC_SliderHandle) - flags |= Style_Active; - drawKStylePrimitive( KPE_SliderHandle, &p2, widget, handle, cg, flags, opt ); - } - - p2.end(); - bitBlt((TQWidget*)widget, r.x(), r.y(), &pix); - break; - } - - // LISTVIEW - // ------------------------------------------------------------------- - case CC_ListView: { - - /* - * Many thanks to TrollTech AS for donating CC_ListView from TQWindowsStyle. - * CC_ListView code is Copyright (C) 1998-2000 TrollTech AS. - */ - - // Paint the icon and text. - if ( controls & SC_ListView ) - TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, flags, controls, active, opt ); - - // If we're have a branch or are expanded... - if ( controls & (SC_ListViewBranch | SC_ListViewExpand) ) - { - // If no list view item was supplied, break - if (opt.isDefault()) - break; - - TQListViewItem *item = opt.listViewItem(); - TQListViewItem *child = item->firstChild(); - - int y = r.y(); - int c; // dotline vertice count - int dotoffset = 0; - TQPointArray dotlines; - - if ( active == SC_All && controls == SC_ListViewExpand ) { - // We only need to draw a vertical line - c = 2; - dotlines.resize(2); - dotlines[0] = TQPoint( r.right(), r.top() ); - dotlines[1] = TQPoint( r.right(), r.bottom() ); - - } else { - - int linetop = 0, linebot = 0; - // each branch needs at most two lines, ie. four end points - dotoffset = (item->itemPos() + item->height() - y) % 2; - dotlines.resize( item->childCount() * 4 ); - c = 0; - - // skip the stuff above the exposed rectangle - while ( child && y + child->height() <= 0 ) - { - y += child->totalHeight(); - child = nextVisibleSibling(child); - } - - int bx = r.width() / 2; - - // paint stuff in the magical area - TQListView* v = item->listView(); - int lh = QMAX( p->fontMetrics().height() + 2 * v->itemMargin(), - TQApplication::globalStrut().height() ); - if ( lh % 2 > 0 ) - lh++; - - // Draw all the expand/close boxes... - TQRect boxrect; - TQStyle::StyleFlags boxflags; - while ( child && y < r.height() ) - { - linebot = y + lh/2; - if ( (child->isExpandable() || child->childCount()) && - (child->height() > 0) ) - { - // The primitive requires a rect. - boxrect = TQRect( bx-4, linebot-4, 9, 9 ); - boxflags = child->isOpen() ? TQStyle::Style_Off : TQStyle::Style_On; - - // KStyle extension: Draw the box and expand/collapse indicator - drawKStylePrimitive( KPE_ListViewExpander, p, NULL, boxrect, cg, boxflags, opt ); - - // dotlinery - p->setPen( cg.mid() ); - dotlines[c++] = TQPoint( bx, linetop ); - dotlines[c++] = TQPoint( bx, linebot - 5 ); - dotlines[c++] = TQPoint( bx + 5, linebot ); - dotlines[c++] = TQPoint( r.width(), linebot ); - linetop = linebot + 5; - } else { - // just dotlinery - dotlines[c++] = TQPoint( bx+1, linebot ); - dotlines[c++] = TQPoint( r.width(), linebot ); - } - - y += child->totalHeight(); - child = nextVisibleSibling(child); - } - - if ( child ) // there's a child to draw, so move linebot to edge of rectangle - linebot = r.height(); - - if ( linetop < linebot ) - { - dotlines[c++] = TQPoint( bx, linetop ); - dotlines[c++] = TQPoint( bx, linebot ); - } - } - - // Draw all the branches... - static int thickness = kPixelMetric( KPM_ListViewBranchThickness ); - int line; // index into dotlines - TQRect branchrect; - TQStyle::StyleFlags branchflags; - for( line = 0; line < c; line += 2 ) - { - // assumptions here: lines are horizontal or vertical. - // lines always start with the numerically lowest - // coordinate. - - // point ... relevant coordinate of current point - // end ..... same coordinate of the end of the current line - // other ... the other coordinate of the current point/line - if ( dotlines[line].y() == dotlines[line+1].y() ) - { - // Horizontal branch - int end = dotlines[line+1].x(); - int point = dotlines[line].x(); - int other = dotlines[line].y(); - - branchrect = TQRect( point, other-(thickness/2), end-point, thickness ); - branchflags = TQStyle::Style_Horizontal; - - // KStyle extension: Draw the horizontal branch - drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt ); - - } else { - // Vertical branch - int end = dotlines[line+1].y(); - int point = dotlines[line].y(); - int other = dotlines[line].x(); - int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0; - - branchrect = TQRect( other-(thickness/2), point, thickness, end-point ); - if (!pixmapoffset) // ### Hackish - used to hint the offset - branchflags = TQStyle::Style_NoChange; - else - branchflags = TQStyle::Style_Default; - - // KStyle extension: Draw the vertical branch - drawKStylePrimitive( KPE_ListViewBranch, p, NULL, branchrect, cg, branchflags, opt ); - } - } - } - break; - } - - default: - TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, - flags, controls, active, opt ); - break; - } -} - - -TQStyle::SubControl KStyle::querySubControl( TQ_ComplexControl control, - const TQWidget* widget, - const TQPoint &pos, - const TQStyleOption &opt ) const -{ - TQStyle::SubControl ret = TQCommonStyle::querySubControl(control, widget, pos, opt); - - if (d->scrollbarType == ThreeButtonScrollBar) { - // Enable third button - if (control == CC_ScrollBar && ret == SC_None) - ret = SC_ScrollBarSubLine; - } - return ret; -} - - -TQRect KStyle::querySubControlMetrics( TQ_ComplexControl control, - const TQWidget* widget, - SubControl sc, - const TQStyleOption &opt ) const -{ - TQRect ret; - - if (control == CC_ScrollBar) - { - bool threeButtonScrollBar = d->scrollbarType & ThreeButtonScrollBar; - bool platinumScrollBar = d->scrollbarType & PlatinumStyleScrollBar; - bool nextScrollBar = d->scrollbarType & NextStyleScrollBar; - - const TQScrollBar *sb = (const TQScrollBar*)widget; - bool horizontal = sb->orientation() == Qt::Horizontal; - int sliderstart = sb->sliderStart(); - int sbextent = tqpixelMetric(PM_ScrollBarExtent, widget); - int maxlen = (horizontal ? sb->width() : sb->height()) - - (sbextent * (threeButtonScrollBar ? 3 : 2)); - int sliderlen; - - // calculate slider length - if (sb->maxValue() != sb->minValue()) - { - uint range = sb->maxValue() - sb->minValue(); - sliderlen = (sb->pageStep() * maxlen) / (range + sb->pageStep()); - - int slidermin = tqpixelMetric( PM_ScrollBarSliderMin, widget ); - if ( sliderlen < slidermin || range > INT_MAX / 2 ) - sliderlen = slidermin; - if ( sliderlen > maxlen ) - sliderlen = maxlen; - } else - sliderlen = maxlen; - - // Subcontrols - switch (sc) - { - case SC_ScrollBarSubLine: { - // top/left button - if (platinumScrollBar) { - if (horizontal) - ret.setRect(sb->width() - 2 * sbextent, 0, sbextent, sbextent); - else - ret.setRect(0, sb->height() - 2 * sbextent, sbextent, sbextent); - } else - ret.setRect(0, 0, sbextent, sbextent); - break; - } - - case SC_ScrollBarAddLine: { - // bottom/right button - if (nextScrollBar) { - if (horizontal) - ret.setRect(sbextent, 0, sbextent, sbextent); - else - ret.setRect(0, sbextent, sbextent, sbextent); - } else { - if (horizontal) - ret.setRect(sb->width() - sbextent, 0, sbextent, sbextent); - else - ret.setRect(0, sb->height() - sbextent, sbextent, sbextent); - } - break; - } - - case SC_ScrollBarSubPage: { - // between top/left button and slider - if (platinumScrollBar) { - if (horizontal) - ret.setRect(0, 0, sliderstart, sbextent); - else - ret.setRect(0, 0, sbextent, sliderstart); - } else if (nextScrollBar) { - if (horizontal) - ret.setRect(sbextent*2, 0, sliderstart-2*sbextent, sbextent); - else - ret.setRect(0, sbextent*2, sbextent, sliderstart-2*sbextent); - } else { - if (horizontal) - ret.setRect(sbextent, 0, sliderstart - sbextent, sbextent); - else - ret.setRect(0, sbextent, sbextent, sliderstart - sbextent); - } - break; - } - - case SC_ScrollBarAddPage: { - // between bottom/right button and slider - int fudge; - - if (platinumScrollBar) - fudge = 0; - else if (nextScrollBar) - fudge = 2*sbextent; - else - fudge = sbextent; - - if (horizontal) - ret.setRect(sliderstart + sliderlen, 0, - maxlen - sliderstart - sliderlen + fudge, sbextent); - else - ret.setRect(0, sliderstart + sliderlen, sbextent, - maxlen - sliderstart - sliderlen + fudge); - break; - } - - case SC_ScrollBarGroove: { - int multi = threeButtonScrollBar ? 3 : 2; - int fudge; - - if (platinumScrollBar) - fudge = 0; - else if (nextScrollBar) - fudge = 2*sbextent; - else - fudge = sbextent; - - if (horizontal) - ret.setRect(fudge, 0, sb->width() - sbextent * multi, sb->height()); - else - ret.setRect(0, fudge, sb->width(), sb->height() - sbextent * multi); - break; - } - - case SC_ScrollBarSlider: { - if (horizontal) - ret.setRect(sliderstart, 0, sliderlen, sbextent); - else - ret.setRect(0, sliderstart, sbextent, sliderlen); - break; - } - - default: - ret = TQCommonStyle::querySubControlMetrics(control, widget, sc, opt); - break; - } - } else - ret = TQCommonStyle::querySubControlMetrics(control, widget, sc, opt); - - return ret; -} - -static const char * const kstyle_close_xpm[] = { -"12 12 2 1", -"# c #000000", -". c None", -"............", -"............", -"..##....##..", -"...##..##...", -"....####....", -".....##.....", -"....####....", -"...##..##...", -"..##....##..", -"............", -"............", -"............"}; - -static const char * const kstyle_maximize_xpm[]={ -"12 12 2 1", -"# c #000000", -". c None", -"............", -"............", -".##########.", -".##########.", -".#........#.", -".#........#.", -".#........#.", -".#........#.", -".#........#.", -".#........#.", -".##########.", -"............"}; - - -static const char * const kstyle_minimize_xpm[] = { -"12 12 2 1", -"# c #000000", -". c None", -"............", -"............", -"............", -"............", -"............", -"............", -"............", -"...######...", -"...######...", -"............", -"............", -"............"}; - -static const char * const kstyle_normalizeup_xpm[] = { -"12 12 2 1", -"# c #000000", -". c None", -"............", -"...#######..", -"...#######..", -"...#.....#..", -".#######.#..", -".#######.#..", -".#.....#.#..", -".#.....###..", -".#.....#....", -".#.....#....", -".#######....", -"............"}; - - -static const char * const kstyle_shade_xpm[] = { -"12 12 2 1", -"# c #000000", -". c None", -"............", -"............", -"............", -"............", -"............", -".....#......", -"....###.....", -"...#####....", -"..#######...", -"............", -"............", -"............"}; - -static const char * const kstyle_unshade_xpm[] = { -"12 12 2 1", -"# c #000000", -". c None", -"............", -"............", -"............", -"............", -"..#######...", -"...#####....", -"....###.....", -".....#......", -"............", -"............", -"............", -"............"}; - -static const char * const dock_window_close_xpm[] = { -"8 8 2 1", -"# c #000000", -". c None", -"##....##", -".##..##.", -"..####..", -"...##...", -"..####..", -".##..##.", -"##....##", -"........"}; - -// Message box icons, from page 210 of the Windows style guide. - -// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape -// palette. The "question mark" icon, which Microsoft recommends not -// using but a lot of people still use, is left out. - -/* XPM */ -static const char * const information_xpm[]={ -"32 32 5 1", -". c None", -"c c #000000", -"* c #999999", -"a c #ffffff", -"b c #0000ff", -"...........********.............", -"........***aaaaaaaa***..........", -"......**aaaaaaaaaaaaaa**........", -".....*aaaaaaaaaaaaaaaaaa*.......", -"....*aaaaaaaabbbbaaaaaaaac......", -"...*aaaaaaaabbbbbbaaaaaaaac.....", -"..*aaaaaaaaabbbbbbaaaaaaaaac....", -".*aaaaaaaaaaabbbbaaaaaaaaaaac...", -".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..", -"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.", -"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.", -"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", -"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", -"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", -"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", -"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**", -".*aaaaaaaaaaabbbbbaaaaaaaaaac***", -".*aaaaaaaaaaabbbbbaaaaaaaaaac***", -"..*aaaaaaaaaabbbbbaaaaaaaaac***.", -"...caaaaaaabbbbbbbbbaaaaaac****.", -"....caaaaaaaaaaaaaaaaaaaac****..", -".....caaaaaaaaaaaaaaaaaac****...", -"......ccaaaaaaaaaaaaaacc****....", -".......*cccaaaaaaaaccc*****.....", -"........***cccaaaac*******......", -"..........****caaac*****........", -".............*caaac**...........", -"...............caac**...........", -"................cac**...........", -".................cc**...........", -"..................***...........", -"...................**..........."}; -/* XPM */ -static const char* const warning_xpm[]={ -"32 32 4 1", -". c None", -"a c #ffff00", -"* c #000000", -"b c #999999", -".............***................", -"............*aaa*...............", -"...........*aaaaa*b.............", -"...........*aaaaa*bb............", -"..........*aaaaaaa*bb...........", -"..........*aaaaaaa*bb...........", -".........*aaaaaaaaa*bb..........", -".........*aaaaaaaaa*bb..........", -"........*aaaaaaaaaaa*bb.........", -"........*aaaa***aaaa*bb.........", -".......*aaaa*****aaaa*bb........", -".......*aaaa*****aaaa*bb........", -"......*aaaaa*****aaaaa*bb.......", -"......*aaaaa*****aaaaa*bb.......", -".....*aaaaaa*****aaaaaa*bb......", -".....*aaaaaa*****aaaaaa*bb......", -"....*aaaaaaaa***aaaaaaaa*bb.....", -"....*aaaaaaaa***aaaaaaaa*bb.....", -"...*aaaaaaaaa***aaaaaaaaa*bb....", -"...*aaaaaaaaaa*aaaaaaaaaa*bb....", -"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...", -"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...", -".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..", -".*aaaaaaaaaaa****aaaaaaaaaa*bb..", -"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.", -"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.", -"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", -"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb", -".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb", -"..*************************bbbbb", -"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.", -".....bbbbbbbbbbbbbbbbbbbbbbbbb.."}; -/* XPM */ -static const char* const critical_xpm[]={ -"32 32 4 1", -". c None", -"a c #999999", -"* c #ff0000", -"b c #ffffff", -"...........********.............", -".........************...........", -".......****************.........", -"......******************........", -".....********************a......", -"....**********************a.....", -"...************************a....", -"..*******b**********b*******a...", -"..******bbb********bbb******a...", -".******bbbbb******bbbbb******a..", -".*******bbbbb****bbbbb*******a..", -"*********bbbbb**bbbbb*********a.", -"**********bbbbbbbbbb**********a.", -"***********bbbbbbbb***********aa", -"************bbbbbb************aa", -"************bbbbbb************aa", -"***********bbbbbbbb***********aa", -"**********bbbbbbbbbb**********aa", -"*********bbbbb**bbbbb*********aa", -".*******bbbbb****bbbbb*******aa.", -".******bbbbb******bbbbb******aa.", -"..******bbb********bbb******aaa.", -"..*******b**********b*******aa..", -"...************************aaa..", -"....**********************aaa...", -"....a********************aaa....", -".....a******************aaa.....", -"......a****************aaa......", -".......aa************aaaa.......", -".........aa********aaaaa........", -"...........aaaaaaaaaaa..........", -".............aaaaaaa............"}; - -TQPixmap KStyle::stylePixmap( StylePixmap stylepixmap, - const TQWidget* widget, - const TQStyleOption& opt) const -{ - switch (stylepixmap) { - case SP_TitleBarShadeButton: - return TQPixmap(const_cast<const char**>(kstyle_shade_xpm)); - case SP_TitleBarUnshadeButton: - return TQPixmap(const_cast<const char**>(kstyle_unshade_xpm)); - case SP_TitleBarNormalButton: - return TQPixmap(const_cast<const char**>(kstyle_normalizeup_xpm)); - case SP_TitleBarMinButton: - return TQPixmap(const_cast<const char**>(kstyle_minimize_xpm)); - case SP_TitleBarMaxButton: - return TQPixmap(const_cast<const char**>(kstyle_maximize_xpm)); - case SP_TitleBarCloseButton: - return TQPixmap(const_cast<const char**>(kstyle_close_xpm)); - case SP_DockWindowCloseButton: - return TQPixmap(const_cast<const char**>(dock_window_close_xpm )); - case SP_MessageBoxInformation: - return TQPixmap(const_cast<const char**>(information_xpm)); - case SP_MessageBoxWarning: - return TQPixmap(const_cast<const char**>(warning_xpm)); - case SP_MessageBoxCritical: - return TQPixmap(const_cast<const char**>(critical_xpm)); - default: - break; - } - return TQCommonStyle::stylePixmap(stylepixmap, widget, opt); -} - - -int KStyle::tqstyleHint( TQ_StyleHint sh, const TQWidget* w, - const TQStyleOption &opt, TQStyleHintReturn* shr) const -{ - switch (sh) - { - case SH_EtchDisabledText: - return d->etchDisabledText ? 1 : 0; - - case SH_PopupMenu_Scrollable: - return d->scrollablePopupmenus ? 1 : 0; - - case SH_MenuBar_AltKeyNavigation: - return d->menuAltKeyNavigation ? 1 : 0; - - case SH_PopupMenu_SubMenuPopupDelay: - if ( tqstyleHint( SH_PopupMenu_SloppySubMenus, w ) ) - return QMIN( 100, d->popupMenuDelay ); - else - return d->popupMenuDelay; - - case SH_PopupMenu_SloppySubMenus: - return d->sloppySubMenus; - - case SH_ItemView_ChangeHighlightOnFocus: - case SH_Slider_SloppyKeyEvents: - case SH_MainWindow_SpaceBelowMenuBar: - case SH_PopupMenu_AllowActiveAndDisabled: - return 0; - - case SH_Slider_SnapToValue: - case SH_PrintDialog_RightAlignButtons: - case SH_FontDialog_SelectAssociatedText: - case SH_MenuBar_MouseTracking: - case SH_PopupMenu_MouseTracking: - case SH_ComboBox_ListMouseTracking: - case SH_ScrollBar_MiddleClickAbsolutePosition: - return 1; - case SH_LineEdit_PasswordCharacter: - { - if (w) { - const TQFontMetrics &fm = w->fontMetrics(); - if (fm.inFont(TQChar(0x25CF))) { - return 0x25CF; - } else if (fm.inFont(TQChar(0x2022))) { - return 0x2022; - } - } - return '*'; - } - - default: - return TQCommonStyle::tqstyleHint(sh, w, opt, shr); - } -} - - -bool KStyle::eventFilter( TQObject* object, TQEvent* event ) -{ - if ( d->useFilledFrameWorkaround ) - { - // Make the QMenuBar/TQToolBar paintEvent() cover a larger area to - // ensure that the filled frame contents are properly painted. - // We essentially modify the paintEvent's rect to include the - // panel border, which also paints the widget's interior. - // This is nasty, but I see no other way to properly tqrepaint - // filled frames in all QMenuBars and QToolBars. - // -- Karol. - TQFrame *frame = 0; - if ( event->type() == TQEvent::Paint - && (frame = ::tqqt_cast<TQFrame*>(object)) ) - { - if (frame->frameShape() != TQFrame::ToolBarPanel && frame->frameShape() != TQFrame::MenuBarPanel) - return false; - - bool horizontal = true; - TQPaintEvent* pe = (TQPaintEvent*)event; - TQToolBar *toolbar = ::tqqt_cast< TQToolBar *>( frame ); - TQRect r = pe->rect(); - - if (toolbar && toolbar->orientation() == Qt::Vertical) - horizontal = false; - - if (horizontal) { - if ( r.height() == frame->height() ) - return false; // Let TQFrame handle the painting now. - - // Else, send a new paint event with an updated paint rect. - TQPaintEvent dummyPE( TQRect( r.x(), 0, r.width(), frame->height()) ); - TQApplication::sendEvent( frame, &dummyPE ); - } - else { // Vertical - if ( r.width() == frame->width() ) - return false; - - TQPaintEvent dummyPE( TQRect( 0, r.y(), frame->width(), r.height()) ); - TQApplication::sendEvent( frame, &dummyPE ); - } - - // Discard this event as we sent a new paintEvent. - return true; - } - } - - return false; -} - - -// ----------------------------------------------------------------------------- -// I N T E R N A L - KStyle menu transparency handler -// ----------------------------------------------------------------------------- - -TransparencyHandler::TransparencyHandler( KStyle* style, - TransparencyEngine tEngine, float menuOpacity, bool useDropShadow ) - : TQObject() -{ - te = tEngine; - kstyle = style; - opacity = menuOpacity; - dropShadow = useDropShadow; - pix.setOptimization(TQPixmap::BestOptim); -} - -TransparencyHandler::~TransparencyHandler() -{ -} - -bool TransparencyHandler::haveX11RGBASupport() -{ - // Simple way to determine if we have ARGB support - if (TQPaintDevice::x11AppDepth() == 32) { - return true; - } - else { - return false; - } -} - -#define REAL_ALPHA_STRENGTH 255.0 - -// This is meant to be ugly but fast. -void TransparencyHandler::rightShadow(TQImage& dst) -{ - bool have_composite = haveX11RGBASupport(); - - if (dst.depth() != 32) - dst = dst.convertDepth(32); - - // blend top-right corner. - int pixels = dst.width() * dst.height(); -#ifdef WORDS_BIGENDIAN - register unsigned char* data = dst.bits() + 1; // Skip alpha -#else - register unsigned char* data = dst.bits(); // Skip alpha -#endif - for(register int i = 0; i < 16; i++) { - if (have_composite) { - data++; - data++; - data++; - *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-top_right_corner[i])); data++; - } - else { - *data = (unsigned char)((*data)*top_right_corner[i]); data++; - *data = (unsigned char)((*data)*top_right_corner[i]); data++; - *data = (unsigned char)((*data)*top_right_corner[i]); data++; - data++; // skip alpha - } - } - - pixels -= 32; // tint right strip without rounded edges. - register int c = 0; - for(register int i = 0; i < pixels; i++) { - if (have_composite) { - data++; - data++; - data++;; - *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-shadow_strip[c])); data++; - } - else { - *data = (unsigned char)((*data)*shadow_strip[c]); data++; - *data = (unsigned char)((*data)*shadow_strip[c]); data++; - *data = (unsigned char)((*data)*shadow_strip[c]); data++; - data++; // skip alpha - } - ++c; - c %= 4; - } - - // tint bottom edge - for(register int i = 0; i < 16; i++) { - if (have_composite) { - data++; - data++; - data++; - *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-bottom_right_corner[i])); data++; - } - else { - *data = (unsigned char)((*data)*bottom_right_corner[i]); data++; - *data = (unsigned char)((*data)*bottom_right_corner[i]); data++; - *data = (unsigned char)((*data)*bottom_right_corner[i]); data++; - data++; // skip alpha - } - } -} - -void TransparencyHandler::bottomShadow(TQImage& dst) -{ - bool have_composite = haveX11RGBASupport(); - - if (dst.depth() != 32) - dst = dst.convertDepth(32); - - int line = 0; - int width = dst.width() - 4; - double strip_data = shadow_strip[0]; - double* corner = const_cast<double*>(bottom_left_corner); - -#ifdef WORDS_BIGENDIAN - register unsigned char* data = dst.bits() + 1; // Skip alpha -#else - register unsigned char* data = dst.bits(); // Skip alpha -#endif - - for(int y = 0; y < 4; y++) - { - // Bottom-left Corner - for(register int x = 0; x < 4; x++) { - if (have_composite) { - data++; - data++; - data++; - *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-(*corner))); data++; - } - else { - *data = (unsigned char)((*data)*(*corner)); data++; - *data = (unsigned char)((*data)*(*corner)); data++; - *data = (unsigned char)((*data)*(*corner)); data++; - data++; // skip alpha - } - corner++; - } - - // Scanline - for(register int x = 0; x < width; x++) { - if (have_composite) { - data++; - data++; - data++; - *data = (unsigned char)(REAL_ALPHA_STRENGTH*(1.0-strip_data)); data++; - } - else { - *data = (unsigned char)((*data)*strip_data); data++; - *data = (unsigned char)((*data)*strip_data); data++; - *data = (unsigned char)((*data)*strip_data); data++; - data++; // skip alpha - } - } - - strip_data = shadow_strip[++line]; - } -} - -TQImage TransparencyHandler::handleRealAlpha(TQImage img) { - TQImage clearImage = img.convertDepth(32); - clearImage.setAlphaBuffer(true); - - int w = clearImage.width(); - int h = clearImage.height(); - - for (int y = 0; y < h; ++y) { - TQRgb *ls = (TQRgb *)clearImage.scanLine( y ); - for (int x = 0; x < w; ++x) { - TQRgb l = ls[x]; - ls[x] = tqRgba( 0, 0, 0, 0 ); - } - } - - return clearImage; -} - -// Create a shadow of thickness 4. -void TransparencyHandler::createShadowWindows(const TQWidget* p) -{ -#ifdef Q_WS_X11 - int x2 = p->x()+p->width(); - int y2 = p->y()+p->height(); - TQRect shadow1(x2, p->y() + 4, 4, p->height()); - TQRect shadow2(p->x() + 4, y2, p->width() - 4, 4); - - bool have_composite = haveX11RGBASupport(); - - // Create a fake drop-down shadow effect via blended Xwindows - ShadowElements se; - se.w1 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) ); - se.w2 = new TQWidget(0, 0, (WFlags)(WStyle_Customize | WType_Popup | WX11BypassWM) ); - se.w1->setGeometry(shadow1); - se.w2->setGeometry(shadow2); - XSelectInput(qt_xdisplay(), se.w1->winId(), StructureNotifyMask ); - XSelectInput(qt_xdisplay(), se.w2->winId(), StructureNotifyMask ); - - // Insert a new ShadowMap entry - shadowMap()[p] = se; - - // Some hocus-pocus here to create the drop-shadow. - TQPixmap pix_shadow1; - TQPixmap pix_shadow2; - if (have_composite) { - pix_shadow1 = TQPixmap(shadow1.width(), shadow1.height()); - pix_shadow2 = TQPixmap(shadow2.width(), shadow2.height()); - } - else { - pix_shadow1 = TQPixmap::grabWindow(qt_xrootwin(), - shadow1.x(), shadow1.y(), shadow1.width(), shadow1.height()); - pix_shadow2 = TQPixmap::grabWindow(qt_xrootwin(), - shadow2.x(), shadow2.y(), shadow2.width(), shadow2.height()); - } - - TQImage img; - img = pix_shadow1.convertToImage(); - if (have_composite) img = handleRealAlpha(img); - rightShadow(img); - pix_shadow1.convertFromImage(img); - img = pix_shadow2.convertToImage(); - if (have_composite) img = handleRealAlpha(img); - bottomShadow(img); - pix_shadow2.convertFromImage(img); - - // Set the background pixmaps - se.w1->setErasePixmap(pix_shadow1); - se.w2->setErasePixmap(pix_shadow2); - - // Show the 'shadow' just before showing the popup menu window - // Don't use TQWidget::show() so we don't confuse QEffects, thus causing broken focus. - XMapWindow(qt_xdisplay(), se.w1->winId()); - XMapWindow(qt_xdisplay(), se.w2->winId()); -#else - Q_UNUSED( p ) -#endif -} - -void TransparencyHandler::removeShadowWindows(const TQWidget* p) -{ -#ifdef Q_WS_X11 - ShadowMap::iterator it = shadowMap().find(p); - if (it != shadowMap().end()) - { - ShadowElements se = it.data(); - XUnmapWindow(qt_xdisplay(), se.w1->winId()); // hide - XUnmapWindow(qt_xdisplay(), se.w2->winId()); - XFlush(qt_xdisplay()); // try to hide faster - delete se.w1; - delete se.w2; - shadowMap().erase(it); - } -#else - Q_UNUSED( p ) -#endif -} - -bool TransparencyHandler::eventFilter( TQObject* object, TQEvent* event ) -{ -#if !defined Q_WS_MAC && !defined Q_WS_WIN - // Transparency idea was borrowed from KDE2's "MegaGradient" Style, - // Copyright (C) 2000 Daniel M. Duley <mosfet@kde.org> - - // Added 'fake' menu shadows <04-Jul-2002> -- Karol - TQWidget* p = (TQWidget*)object; - TQEvent::Type et = event->type(); - - if (et == TQEvent::Show) - { - // Handle translucency - if (te != Disabled) - { - pix = TQPixmap::grabWindow(qt_xrootwin(), - p->x(), p->y(), p->width(), p->height()); - - switch (te) { -#ifdef HAVE_XRENDER - case XRender: - if (qt_use_xrender) { - XRenderBlendToPixmap(p); - break; - } - // Fall through intended -#else - case XRender: -#endif - case SoftwareBlend: - blendToPixmap(p->tqcolorGroup(), p); - break; - - case SoftwareTint: - default: - blendToColor(p->tqcolorGroup().button()); - }; - - p->setErasePixmap(pix); - } - - // Handle drop shadow - // * FIXME : !shadowMap().contains(p) is a workaround for leftover - // * shadows after duplicate show events. - // * TODO : determine real cause for duplicate events - // * till 20021005 - if ((dropShadow || useDropShadow(p)) - && p->width() > 16 && p->height() > 16 && !shadowMap().contains( p )) - createShadowWindows(p); - } - else if (et == TQEvent::Resize && p->isShown() && p->isTopLevel()) - { - // Handle drop shadow - if (dropShadow || useDropShadow(p)) - { - removeShadowWindows(p); - createShadowWindows(p); - } - } - else if (et == TQEvent::Hide) - { - // Handle drop shadow - if (dropShadow || useDropShadow(p)) - removeShadowWindows(p); - - // Handle translucency - if (te != Disabled) - p->setErasePixmap(TQPixmap()); - } - -#endif - return false; -} - - -// Blends a TQImage to a predefined color, with a given opacity. -void TransparencyHandler::blendToColor(const TQColor &col) -{ - if (opacity < 0.0 || opacity > 1.0) - return; - - TQImage img = pix.convertToImage(); - KImageEffect::blend(col, img, opacity); - pix.convertFromImage(img); -} - - -void TransparencyHandler::blendToPixmap(const TQColorGroup &cg, const TQWidget* p) -{ - if (opacity < 0.0 || opacity > 1.0) - return; - - KPixmap blendPix; - blendPix.resize( pix.width(), pix.height() ); - - if (blendPix.width() != pix.width() || - blendPix.height() != pix.height()) - return; - - // Allow styles to define the blend pixmap - allows for some interesting effects. - if (::tqqt_cast<TQPopupMenu*>(p)) - kstyle->renderMenuBlendPixmap( blendPix, cg, ::tqqt_cast<TQPopupMenu*>(p) ); - else - blendPix.fill(cg.button()); // Just tint as the default behavior - - TQImage blendImg = blendPix.convertToImage(); - TQImage backImg = pix.convertToImage(); - KImageEffect::blend(blendImg, backImg, opacity); - pix.convertFromImage(backImg); -} - - -#ifdef HAVE_XRENDER -// Here we go, use XRender in all its glory. -// NOTE: This is actually a bit slower than the above routines -// on non-accelerated displays. -- Karol. -void TransparencyHandler::XRenderBlendToPixmap(const TQWidget* p) -{ - KPixmap renderPix; - renderPix.resize( pix.width(), pix.height() ); - - // Allow styles to define the blend pixmap - allows for some interesting effects. - if (::tqqt_cast<TQPopupMenu*>(p)) - kstyle->renderMenuBlendPixmap( renderPix, p->tqcolorGroup(), - ::tqqt_cast<TQPopupMenu*>(p) ); - else - renderPix.fill(p->tqcolorGroup().button()); // Just tint as the default behavior - - Display* dpy = qt_xdisplay(); - Pixmap alphaPixmap; - Picture alphaPicture; - XRenderPictFormat Rpf; - XRenderPictureAttributes Rpa; - XRenderColor clr; - clr.alpha = ((unsigned short)(255*opacity) << 8); - - Rpf.type = PictTypeDirect; - Rpf.depth = 8; - Rpf.direct.alphaMask = 0xff; - Rpa.repeat = True; // Tile - - XRenderPictFormat* xformat = XRenderFindFormat(dpy, - PictFormatType | PictFormatDepth | PictFormatAlphaMask, &Rpf, 0); - - alphaPixmap = XCreatePixmap(dpy, p->handle(), 1, 1, 8); - alphaPicture = XRenderCreatePicture(dpy, alphaPixmap, xformat, CPRepeat, &Rpa); - - XRenderFillRectangle(dpy, PictOpSrc, alphaPicture, &clr, 0, 0, 1, 1); - - XRenderComposite(dpy, PictOpOver, - renderPix.x11RenderHandle(), alphaPicture, pix.x11RenderHandle(), // src, mask, dst - 0, 0, // srcx, srcy - 0, 0, // maskx, masky - 0, 0, // dstx, dsty - pix.width(), pix.height()); - - XRenderFreePicture(dpy, alphaPicture); - XFreePixmap(dpy, alphaPixmap); -} -#endif - -void KStyle::virtual_hook( int, void* ) -{ /*BASE::virtual_hook( id, data );*/ } - -// HACK for gtk-qt-engine - -KDE_EXPORT extern "C" -void kde_kstyle_set_scrollbar_type_windows( void* style ) -{ - ((KStyle*)style)->setScrollBarType( KStyle::WindowsStyleScrollBar ); -} - -// vim: set noet ts=4 sw=4: -// kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off; - -#include "kstyle.moc" diff --git a/kdefx/kstyle.h b/kdefx/kstyle.h deleted file mode 100644 index 42bd1a231..000000000 --- a/kdefx/kstyle.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * $Id$ - * - * KStyle - * Copyright (C) 2001-2002 Karol Szwed <gallium@kde.org> - * - * TQWindowsStyle CC_ListView and style images were kindly donated by TrollTech, - * Copyright (C) 1998-2000 TrollTech AS. - * - * Many thanks to Bradley T. Hughes for the 3 button scrollbar code. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License version 2 as published by the Free Software Foundation. - * - * 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., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef __KSTYLE_H -#define __KSTYLE_H - -// W A R N I N G -// ------------- -// This API is still subject to change. -// I will remove this warning when I feel the API is sufficiently flexible. - -#include <tqcommonstyle.h> - -#include <kdelibs_export.h> - -class KPixmap; - -struct KStylePrivate; -/** - * Simplifies and extends the TQStyle API to make style coding easier. - * - * The KStyle class provides a simple internal menu transparency engine - * which attempts to use XRender for accelerated blending where requested, - * or falls back to fast internal software tinting/blending routines. - * It also simplifies more complex portions of the TQStyle API, such as - * the PopupMenuItems, ScrollBars and Sliders by providing extra "primitive - * elements" which are simple to implement by the style writer. - * - * @see TQStyle::QStyle - * @see TQCommonStyle::QCommonStyle - * @author Karol Szwed (gallium@kde.org) - * @version $Id$ - */ -class KDEFX_EXPORT KStyle: public TQCommonStyle -{ - Q_OBJECT - TQ_OBJECT - - public: - - /** - * KStyle Flags: - * - * @li Default - Default style setting, where menu transparency - * and the FilledFrameWorkaround are disabled. - * - * @li AllowMenuTransparency - Enable this flag to use KStyle's - * internal menu transparency engine. - * - * @li FilledFrameWorkaround - Enable this flag to facilitate - * proper repaints of QMenuBars and QToolBars when the style chooses - * to paint the interior of a TQFrame. The style primitives in question - * are PE_PanelMenuBar and PE_PanelDockWindow. The HighColor style uses - * this workaround to enable painting of gradients in menubars and - * toolbars. - */ - typedef uint KStyleFlags; - enum KStyleOption { - Default = 0x00000000, //!< All options disabled - AllowMenuTransparency = 0x00000001, //!< Internal transparency enabled - FilledFrameWorkaround = 0x00000002 //!< Filled frames enabled - }; - - /** - * KStyle ScrollBarType: - * - * Allows the style writer to easily select what type of scrollbar - * should be used without having to duplicate large amounts of source - * code by implementing the complex control CC_ScrollBar. - * - * @li WindowsStyleScrollBar - Two button scrollbar with the previous - * button at the top/left, and the next button at the bottom/right. - * - * @li PlatinumStyleScrollBar - Two button scrollbar with both the - * previous and next buttons at the bottom/right. - * - * @li ThreeButtonScrollBar - %KDE style three button scrollbar with - * two previous buttons, and one next button. The next button is always - * at the bottom/right, whilst the two previous buttons are on either - * end of the scrollbar. - * - * @li NextStyleScrollBar - Similar to the PlatinumStyle scroll bar, but - * with the buttons grouped on the opposite end of the scrollbar. - * - * @see KStyle::KStyle() - */ - enum KStyleScrollBarType { - WindowsStyleScrollBar = 0x00000000, //!< two button, windows style - PlatinumStyleScrollBar = 0x00000001, //!< two button, platinum style - ThreeButtonScrollBar = 0x00000002, //!< three buttons, %KDE style - NextStyleScrollBar = 0x00000004 //!< two button, NeXT style - }; - - /** - * Constructs a KStyle object. - * - * Select the appropriate KStyle flags and scrollbar type - * for your style. The user's style preferences selected in KControl - * are read by using TQSettings and are automatically applied to the style. - * As a fallback, KStyle paints progressbars and tabbars. It inherits from - * TQCommonStyle for speed, so don't expect much to be implemented. - * - * It is advisable to use a currently implemented style such as the HighColor - * style as a foundation for any new KStyle, so the limited number of - * drawing fallbacks should not prove problematic. - * - * @param flags the style to be applied - * @param sbtype the scroll bar type - * @see KStyle::KStyleFlags - * @see KStyle::KStyleScrollBarType - * @author Karol Szwed (gallium@kde.org) - */ - KStyle( KStyleFlags flags = KStyle::Default, - KStyleScrollBarType sbtype = KStyle::WindowsStyleScrollBar ); - - /** - * Destructs the KStyle object. - */ - ~KStyle(); - - /** - * Returns the default widget style depending on color depth. - */ - static TQString defaultStyle(); - - /** - * Modifies the scrollbar type used by the style. - * - * This function is only provided for convenience. It allows - * you to make a late decision about what scrollbar type to use for the - * style after performing some processing in your style's constructor. - * In most situations however, setting the scrollbar type via the KStyle - * constructor should suffice. - * @param sbtype the scroll bar type - * @see KStyle::KStyleScrollBarType - */ - void setScrollBarType(KStyleScrollBarType sbtype); - - /** - * Returns the KStyle flags used to initialize the style. - * - * This is used solely for the kcmstyle module, and hence is internal. - */ - KStyleFlags styleFlags() const; - - // --------------------------------------------------------------------------- - - /** - * This virtual function defines the pixmap used to blend between the popup - * menu and the background to create different menu transparency effects. - * For example, you can fill the pixmap "pix" with a gradient based on the - * popup's tqcolorGroup, a texture, or some other fancy painting routine. - * KStyle will then internally blend this pixmap with a snapshot of the - * background behind the popupMenu to create the illusion of transparency. - * - * This virtual is never called if XRender/Software blending is disabled by - * the user in KDE's style control module. - */ - virtual void renderMenuBlendPixmap( KPixmap& pix, const TQColorGroup& cg, - const TQPopupMenu* popup ) const; - - /** - * KStyle Primitive Elements: - * - * The KStyle class extends the Qt's Style API by providing certain - * simplifications for parts of TQStyle. To do this, the KStylePrimitive - * elements were defined, which are very similar to Qt's PrimitiveElement. - * - * The first three Handle primitives simplify and extend PE_DockWindowHandle, - * so do not reimplement PE_DockWindowHandle if you want the KStyle handle - * simplifications to be operable. Similarly do not reimplement CC_Slider, - * SC_SliderGroove and SC_SliderHandle when using the KStyle slider - * primitives. KStyle automatically double-buffers slider painting - * when they are drawn via these KStyle primitives to avoid flicker. - * - * @li KPE_DockWindowHandle - This primitive is already implemented in KStyle, - * and paints a bevelled rect with the DockWindow caption text. Re-implement - * this primitive to perform other more fancy effects when drawing the dock window - * handle. - * - * @li KPE_ToolBarHandle - This primitive must be reimplemented. It currently - * only paints a filled rectangle as default behavior. This primitive is used - * to render TQToolBar handles. - * - * @li KPE_GeneralHandle - This primitive must be reimplemented. It is used - * to render general handles that are not part of a TQToolBar or TQDockWindow, such - * as the applet handles used in Kicker. The default implementation paints a filled - * rect of arbitrary color. - * - * @li KPE_SliderGroove - This primitive must be reimplemented. It is used to - * paint the slider groove. The default implementation paints a filled rect of - * arbitrary color. - * - * @li KPE_SliderHandle - This primitive must be reimplemented. It is used to - * paint the slider handle. The default implementation paints a filled rect of - * arbitrary color. - * - * @li KPE_ListViewExpander - This primitive is already implemented in KStyle. It - * is used to draw the Expand/Collapse element in QListViews. To indicate the - * expanded state, the style flags are set to Style_Off, while Style_On implies collapsed. - * - * @li KPE_ListViewBranch - This primitive is already implemented in KStyle. It is - * used to draw the ListView branches where necessary. - */ - enum KStylePrimitive { - KPE_DockWindowHandle, - KPE_ToolBarHandle, - KPE_GeneralHandle, - - KPE_SliderGroove, - KPE_SliderHandle, - - KPE_ListViewExpander, - KPE_ListViewBranch - }; - - /** - * This function is identical to Qt's TQStyle::tqdrawPrimitive(), except that - * it adds one further parameter, 'widget', that can be used to determine - * the widget state of the KStylePrimitive in question. - * - * @see KStyle::KStylePrimitive - * @see TQStyle::tqdrawPrimitive - * @see TQStyle::tqdrawComplexControl - */ - virtual void drawKStylePrimitive( KStylePrimitive kpe, - TQPainter* p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags = Style_Default, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - - enum KStylePixelMetric { - KPM_MenuItemSeparatorHeight = 0x00000001, - KPM_MenuItemHMargin = 0x00000002, - KPM_MenuItemVMargin = 0x00000004, - KPM_MenuItemHFrame = 0x00000008, - KPM_MenuItemVFrame = 0x00000010, - KPM_MenuItemCheckMarkHMargin = 0x00000020, - KPM_MenuItemArrowHMargin = 0x00000040, - KPM_MenuItemTabSpacing = 0x00000080, - KPM_ListViewBranchThickness = 0x00000100 - }; - - int kPixelMetric( KStylePixelMetric kpm, const TQWidget* widget = 0 ) const; - - // --------------------------------------------------------------------------- - - void polish( TQWidget* widget ); - void unPolish( TQWidget* widget ); - void polishPopupMenu( TQPopupMenu* ); - - void tqdrawPrimitive( TQ_PrimitiveElement pe, - TQPainter* p, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags = Style_Default, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - -// #ifdef USE_QT4 // kdebindings / smoke needs this function declaration available at all times. Furthermore I don't think it would hurt to have the declaration available at all times...so leave these commented out for now - -// void tqdrawPrimitive( TQ_ControlElement pe, -// TQPainter* p, -// const TQRect &r, -// const TQColorGroup &cg, -// SFlags flags = Style_Default, -// const TQStyleOption& = TQStyleOption::SO_Default ) const; - -// #endif // USE_QT4 - - void tqdrawControl( TQ_ControlElement element, - TQPainter* p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags = Style_Default, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - void tqdrawComplexControl( TQ_ComplexControl control, - TQPainter *p, - const TQWidget* widget, - const TQRect &r, - const TQColorGroup &cg, - SFlags flags = Style_Default, - SCFlags controls = SC_All, - SCFlags active = SC_None, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - SubControl querySubControl( TQ_ComplexControl control, - const TQWidget* widget, - const TQPoint &pos, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - TQRect querySubControlMetrics( TQ_ComplexControl control, - const TQWidget* widget, - SubControl sc, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - int tqpixelMetric( PixelMetric m, - const TQWidget* widget = 0 ) const; - - TQRect subRect( SubRect r, - const TQWidget* widget ) const; - - TQPixmap stylePixmap( StylePixmap stylepixmap, - const TQWidget* widget = 0, - const TQStyleOption& = TQStyleOption::SO_Default ) const; - - int tqstyleHint( TQ_StyleHint sh, - const TQWidget* w = 0, - const TQStyleOption &opt = TQStyleOption::SO_Default, - TQStyleHintReturn* shr = 0 ) const; - - protected: - bool eventFilter( TQObject* object, TQEvent* event ); - - private: - // Disable copy constructor and = operator - KStyle( const KStyle & ); - KStyle& operator=( const KStyle & ); - - protected: - virtual void virtual_hook( int id, void* data ); - private: - KStylePrivate *d; -}; - - -// vim: set noet ts=4 sw=4: -#endif - diff --git a/kdefx/libkdefx.nmcheck b/kdefx/libkdefx.nmcheck deleted file mode 100644 index bebebf28c..000000000 --- a/kdefx/libkdefx.nmcheck +++ /dev/null @@ -1,12 +0,0 @@ -# KDE namespace check file - -# tdefx classes -K*::* - -# these should preferably go in some namespace in KDE4 -kColorBitmaps -kDrawBeButton -kDrawRoundMask -kDrawNextButton -kDrawRoundButton -kRoundMaskRegion diff --git a/kdefx/libkdefx_weak.nmcheck b/kdefx/libkdefx_weak.nmcheck deleted file mode 100644 index 6482e1938..000000000 --- a/kdefx/libkdefx_weak.nmcheck +++ /dev/null @@ -1,3 +0,0 @@ -# KDE namespace check file - -# KDE classes |